diff --git a/.eslintrc.js b/.eslintrc.js
index f59f65f8065c58..8279dfc9c4ab41 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -59,7 +59,7 @@ module.exports = {
],
rules: {
// ESLint built-in rules
- // http://eslint.org/docs/rules
+ // https://eslint.org/docs/rules/
'accessor-pairs': 'error',
'array-callback-return': 'error',
'arrow-parens': ['error', 'always'],
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000000000..6fb4f7dc493b6a
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,76 @@
+# Node.js Project Codeowners
+
+# 1. Codeowners must always be teams, never individuals
+# 2. Each codeowner team should contain at least one TSC member
+# 3. PRs touching any code with a codeowner must be signed off by at least one
+# person on the code owner team.
+
+./.github/CODEOWNERS @nodejs/tsc
+
+# net
+
+# ./deps/cares @nodejs/net
+# ./doc/api/dns.md @nodejs/net
+# ./doc/api/dgram.md @nodejs/net
+# ./doc/api/net.md @nodejs/net
+# ./lib/dgram.js @nodejs/net
+# ./lib/dns.js @nodejs/net
+# ./lib/net.js @nodejs/net @nodejs/quic
+# ./lib/internal/dgram.js @nodejs/net
+# ./lib/internal/dns/* @nodejs/net
+# ./lib/internal/net.js @nodejs/net
+# ./lib/internal/socket_list.js @nodejs/net
+# ./lib/internal/js_stream_socket.js @nodejs/net
+# ./src/cares_wrap.h @nodejs/net
+# ./src/connect_wrap.* @nodejs/net
+# ./src/connection_wrap.* @nodejs/net
+# ./src/node_sockaddr* @nodejs/net
+# ./src/tcp_wrap.* @nodejs/net
+# ./src/udp_wrap.* @nodejs/net
+
+# tls/crypto
+
+# ./lib/internal/crypto/* @nodejs/crypto
+# ./lib/internal/tls.js @nodejs/crypto @nodejs/net
+# ./lib/crypto.js @nodejs/crypto
+# ./lib/tls.js @nodejs/crypto @nodejs/net
+# ./src/node_crypto* @nodejs/crypto
+# ./src/node_crypto_common* @nodejs/crypto @nodejs/quic
+
+# http
+
+# ./deps/llhttp/* @nodejs/http @nodejs/net
+# ./doc/api/http.md @nodejs/http @nodejs/net
+# ./doc/api/http2.md @nodejs/http @nodejs/net
+# ./lib/_http_* @nodejs/http @nodejs/net
+# ./lib/http.js @nodejs/http @nodejs/net
+# ./lib/https.js @nodejs/crypto @nodejs/net @nodejs/http
+# ./src/node_http_common* @nodejs/http @nodejs/http2 @nodejs/quic @nodejs/net
+# ./src/node_http_parser.cc @nodejs/http @nodejs/net
+
+# http2
+
+# ./deps/nghttp2/* @nodejs/http2 @nodejs/net
+# ./doc/api/http2.md @nodejs/http2 @nodejs/net
+# ./lib/http2.js @nodejs/http2 @nodejs/net
+# ./lib/internal/http2/* @nodejs/http2 @nodejs/net
+# ./src/node_http2* @nodejs/http2 @nodejs/net
+# ./src/node_mem* @nodejs/http2
+
+# quic
+
+./deps/ngtcp2/* @nodejs/quic
+./deps/nghttp3/* @nodejs/quic
+./doc/api/quic.md @nodejs/quic
+./lib/internal/quic/* @nodejs/quic
+./src/node_bob* @nodejs/quic
+./src/quic/* @nodejs/quic
+
+# modules
+
+# ./doc/api/modules.md @nodejs/modules
+# ./doc/api/esm.md @nodejs/modules
+# ./lib/module.js @nodejs/modules
+# ./lib/internal/modules/* @nodejs/modules
+# ./lib/internal/bootstrap/loaders.js @nodejs/modules
+# ./src/module_wrap* @nodejs/modules @nodejs/vm
diff --git a/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md b/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md
new file mode 100644
index 00000000000000..544c9d5f47b0f5
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md
@@ -0,0 +1,34 @@
+---
+name: Report a flaky test
+about: Report a flaky test in our CI
+labels: "CI / flaky test"
+
+---
+
+
+
+* **Test**:
+* **Platform**:
+* **Console Output:**
+```
+REPLACE ME
+```
+* **Build Links**:
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
index 1a086bd2cc59a7..48ad8a90cb77c5 100644
--- a/.github/SUPPORT.md
+++ b/.github/SUPPORT.md
@@ -17,7 +17,7 @@ resources:
* [Questions tagged 'node.js' on Stack Overflow](https://stackoverflow.com/questions/tagged/node.js)
* [#node.js channel on chat.freenode.net](https://webchat.freenode.net?channels=node.js&uio=d4)
* [Node.js Slack Community](https://node-js.slack.com/)
- * To register: [nodeslackers.com](http://www.nodeslackers.com/)
+ * To register: [nodeslackers.com](https://www.nodeslackers.com/)
GitHub issues are for tracking enhancements and bugs, not general support.
diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml
index b706e7ef855de6..3a3138a677b1d6 100644
--- a/.github/workflows/build-tarball.yml
+++ b/.github/workflows/build-tarball.yml
@@ -63,7 +63,7 @@ jobs:
- name: Test
run: |
cd $TAR_DIR
- make run-ci -j2 V=1
+ make run-ci -j2 V=1 TEST_CI_ARGS="-p dots"
test-tarball-windows:
needs: build-tarball
runs-on: windows-latest
@@ -138,4 +138,4 @@ jobs:
- name: Test
run: |
cd $TAR_DIR
- make run-ci -j8 V=1
\ No newline at end of file
+ make run-ci -j8 V=1 TEST_CI_ARGS="-p dots"
diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
index 9b4ebca75c86ca..4453db5c751c7f 100644
--- a/.github/workflows/linters.yml
+++ b/.github/workflows/linters.yml
@@ -26,7 +26,7 @@ jobs:
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v1
with:
- PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
+ python-version: ${{ env.PYTHON_VERSION }}
- name: Environment Information
run: npx envinfo
- name: Lint C/C++ files
@@ -64,7 +64,7 @@ jobs:
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v1
with:
- PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
+ python-version: ${{ env.PYTHON_VERSION }}
- name: Environment Information
run: npx envinfo
- name: Lint Python
diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml
index 56ad55f6735804..54d6cae049badb 100644
--- a/.github/workflows/test-asan.yml
+++ b/.github/workflows/test-asan.yml
@@ -1,6 +1,12 @@
name: test-asan
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
env:
PYTHON_VERSION: 3.8
@@ -24,5 +30,5 @@ jobs:
run: npx envinfo
- name: Build
run: make build-ci -j2 V=1
- - name: Test cctest
- run: make cctest -j2 V=1
+ - name: Test
+ run: make run-ci -j2 V=1 TEST_CI_ARGS="-p dots"
diff --git a/BUILDING.md b/BUILDING.md
index 13caddbdc13e98..0a8f24c694222e 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -695,7 +695,7 @@ that works for both your host and target environments.
### Build with a specific ICU
You can find other ICU releases at
-[the ICU homepage](http://icu-project.org/download).
+[the ICU homepage](http://site.icu-project.org/download).
Download the file named something like `icu4c-**##.#**-src.tgz` (or
`.zip`).
@@ -726,7 +726,7 @@ $ ./configure --with-intl=full-icu --with-icu-source=http://url/to/icu.tgz
#### Windows
First unpack latest ICU to `deps/icu`
-[icu4c-**##.#**-src.tgz](http://icu-project.org/download) (or `.zip`)
+[icu4c-**##.#**-src.tgz](http://site.icu-project.org/download) (or `.zip`)
as `deps/icu` (You'll have: `deps/icu/source/...`)
```console
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5399fb3266e5c6..ee9cf67a351426 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,7 +31,8 @@ release.
-14.4.0
+14.5.0
+14.4.0
14.3.0
14.2.0
14.1.0
diff --git a/LICENSE b/LICENSE
index b0c33eb5f78f67..0443d15f3c60c2 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1448,6 +1448,39 @@ The externally maintained libraries used by Node.js are:
THE POSSIBILITY OF SUCH DAMAGE.
"""
+- highlight.js, located at doc/api_assets/highlight.pack.js, is licensed as follows:
+ """
+ BSD 3-Clause License
+
+ Copyright (c) 2006, Ivan Sagalaev.
+ 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 the copyright holder 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 HOLDER 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.
+ """
+
- node-heapdump, located at src/heap_utils.cc, is licensed as follows:
"""
ISC License
diff --git a/Makefile b/Makefile
index 43d23459284609..89cd8f68885865 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ GNUMAKEFLAGS += --no-print-directory
GCOV ?= gcov
PWD = $(CURDIR)
BUILD_WITH ?= make
+FIND ?= find
ifdef JOBS
PARALLEL_ARGS = -j $(JOBS)
@@ -97,13 +98,12 @@ help: ## Print help for targets with comments.
# and recreated which can break the addons build when running test-ci
# See comments on the build-addons target for some more info
ifeq ($(BUILD_WITH), make)
-$(NODE_EXE): config.gypi out/Makefile
- $(MAKE) -C out BUILDTYPE=Release V=$(V)
- if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Release/$(NODE_EXE) $@; fi
-
-$(NODE_G_EXE): config.gypi out/Makefile
- $(MAKE) -C out BUILDTYPE=Debug V=$(V)
- if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Debug/$(NODE_EXE) $@; fi
+$(NODE_EXE): build_type:=Release
+$(NODE_G_EXE): build_type:=Debug
+$(NODE_EXE) $(NODE_G_EXE): config.gypi out/Makefile
+ $(MAKE) -C out BUILDTYPE=${build_type} V=$(V)
+ if [ ! -r $@ -o ! -L $@ ]; then \
+ ln -fs out/${build_type}/$(NODE_EXE) $@; fi
else
ifeq ($(BUILD_WITH), ninja)
ifeq ($(V),1)
@@ -168,7 +168,7 @@ uninstall: ## Uninstalls node from $PREFIX (default=/usr/local).
clean: ## Remove build artifacts.
$(RM) -r out/Makefile $(NODE_EXE) $(NODE_G_EXE) out/$(BUILDTYPE)/$(NODE_EXE) \
out/$(BUILDTYPE)/node.exp
- @if [ -d out ]; then find out/ -name '*.o' -o -name '*.a' -o -name '*.d' | xargs $(RM) -r; fi
+ @if [ -d out ]; then $(FIND) out/ -name '*.o' -o -name '*.a' -o -name '*.d' | xargs $(RM) -r; fi
$(RM) -r node_modules
@if [ -d deps/icu ]; then echo deleting deps/icu; $(RM) -r deps/icu; fi
$(RM) test.tap
@@ -737,7 +737,7 @@ out/doc/api/assets:
# If it's not a source tarball, we need to copy assets from doc/api_assets
out/doc/api/assets/%: doc/api_assets/% out/doc/api/assets
- @cp $< $@
+ @cp $< $@ ; $(RM) out/doc/api/assets/README.md
run-npm-ci = $(PWD)/$(NPM) ci
@@ -772,6 +772,11 @@ out/doc/api/all.json: $(apidocs_json) tools/doc/alljson.js
docopen: $(apidocs_html)
@$(PYTHON) -mwebbrowser file://$(PWD)/out/doc/api/all.html
+.PHONY: docserve
+docserve: $(apidocs_html)
+ @$(PYTHON) -mwebbrowser http://localhost:8000/all.html
+ @$(PYTHON) -m http.server -d $(PWD)/out/doc/api
+
.PHONY: docclean
docclean:
$(RM) -r out/doc
@@ -1199,7 +1204,7 @@ LINT_MD_NEWER = -newer tools/.mdlintstamp
endif
LINT_MD_TARGETS = doc src lib benchmark test tools/doc tools/icu $(wildcard *.md)
-LINT_MD_FILES = $(shell find $(LINT_MD_TARGETS) -type f \
+LINT_MD_FILES = $(shell $(FIND) $(LINT_MD_TARGETS) -type f \
! -path '*node_modules*' ! -path 'test/fixtures/*' -name '*.md' \
$(LINT_MD_NEWER))
run-lint-md = tools/lint-md.js -q -f --no-stdout $(LINT_MD_FILES)
@@ -1322,13 +1327,13 @@ else
CPPLINT_QUIET = --quiet
endif
.PHONY: lint-cpp
-# Lints the C++ code with cpplint.py and check-imports.py.
+# Lints the C++ code with cpplint.py and checkimports.py.
lint-cpp: tools/.cpplintstamp
tools/.cpplintstamp: $(LINT_CPP_FILES)
@echo "Running C++ linter..."
@$(PYTHON) tools/cpplint.py $(CPPLINT_QUIET) $?
- @$(PYTHON) tools/check-imports.py
+ @$(PYTHON) tools/checkimports.py $?
@touch $@
.PHONY: lint-addon-docs
@@ -1378,7 +1383,7 @@ CONFLICT_RE=^>>>>>>> [0-9A-Fa-f]+|^<<<<<<< [A-Za-z]+
# Related CI job: node-test-linter
lint-ci: lint-js-ci lint-cpp lint-py lint-md lint-addon-docs
@if ! ( grep -IEqrs "$(CONFLICT_RE)" benchmark deps doc lib src test tools ) \
- && ! ( find . -maxdepth 1 -type f | xargs grep -IEqs "$(CONFLICT_RE)" ); then \
+ && ! ( $(FIND) . -maxdepth 1 -type f | xargs grep -IEqs "$(CONFLICT_RE)" ); then \
exit 0 ; \
else \
echo "" >&2 ; \
diff --git a/README.md b/README.md
index af3a57ccaac992..fda0fc98ea2340 100644
--- a/README.md
+++ b/README.md
@@ -152,6 +152,7 @@ For information about the governance of the Node.js project, see
### TSC (Technical Steering Committee)
+
* [addaleax](https://github.com/addaleax) -
**Anna Henningsen** <anna@addaleax.net> (she/her)
* [apapirovski](https://github.com/apapirovski) -
@@ -545,6 +546,7 @@ For information about the governance of the Node.js project, see
**Vse Mozhet Byt** <vsemozhetbyt@gmail.com> (he/him)
* [whitlockjc](https://github.com/whitlockjc) -
**Jeremy Whitlock** <jwhitlock@apache.org>
+
Collaborators follow the [Collaborator Guide](./doc/guides/collaborator-guide.md) in
maintaining the Node.js project.
@@ -572,7 +574,7 @@ Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys):
To import the full set of trusted release keys:
-```shell
+```bash
gpg --keyserver pool.sks-keyservers.net --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C
gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5
gpg --keyserver pool.sks-keyservers.net --recv-keys 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1
@@ -608,6 +610,6 @@ Other keys used to sign some previous releases:
[Code of Conduct]: https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md
[Contributing to the project]: CONTRIBUTING.md
[Node.js Website]: https://nodejs.org/
-[OpenJS Foundation]: http://openjs.foundation/
+[OpenJS Foundation]: https://openjsf.org/
[Working Groups]: https://github.com/nodejs/TSC/blob/master/WORKING_GROUPS.md
[Strategic Initiatives]: https://github.com/nodejs/TSC/blob/master/Strategic-Initiatives.md
diff --git a/benchmark/async_hooks/async-resource-vs-destroy.js b/benchmark/async_hooks/async-resource-vs-destroy.js
index 52e5e543a6a08d..09898bbe52f939 100644
--- a/benchmark/async_hooks/async-resource-vs-destroy.js
+++ b/benchmark/async_hooks/async-resource-vs-destroy.js
@@ -138,6 +138,7 @@ function getServeAwait(getCLS, setCLS) {
setCLS(Math.random());
await sleep(10);
await read(__filename);
+ if (res.destroyed) return;
res.setHeader('content-type', 'application/json');
res.end(JSON.stringify({ cls: getCLS() }));
};
@@ -148,6 +149,7 @@ function getServeCallbacks(getCLS, setCLS) {
setCLS(Math.random());
setTimeout(() => {
readFile(__filename, () => {
+ if (res.destroyed) return;
res.setHeader('content-type', 'application/json');
res.end(JSON.stringify({ cls: getCLS() }));
});
diff --git a/benchmark/es/spread-assign.js b/benchmark/es/spread-assign.js
index 970512aa6b93d4..c34bb93e762d12 100644
--- a/benchmark/es/spread-assign.js
+++ b/benchmark/es/spread-assign.js
@@ -15,7 +15,7 @@ function main({ n, context, count, rest, method }) {
for (let n = 0; n < count; n++)
src[`p${n}`] = n;
- let obj; // eslint-disable-line no-unused-vars
+ let obj;
switch (method) {
case '_extend':
@@ -33,7 +33,7 @@ function main({ n, context, count, rest, method }) {
case 'spread':
bench.start();
for (let i = 0; i < n; i++)
- obj = { ...src };
+ obj = { ...src }; // eslint-disable-line no-unused-vars
bench.end(n);
break;
default:
diff --git a/benchmark/events/ee-emit.js b/benchmark/events/ee-emit.js
index 39bcbb937d6c56..ec35277a9c0214 100644
--- a/benchmark/events/ee-emit.js
+++ b/benchmark/events/ee-emit.js
@@ -10,6 +10,7 @@ const bench = common.createBenchmark(main, {
function main({ n, argc, listeners }) {
const ee = new EventEmitter();
+ ee.setMaxListeners(listeners + 1);
for (let k = 0; k < listeners; k += 1)
ee.on('dummy', () => {});
diff --git a/benchmark/events/ee-listeners-many.js b/benchmark/events/ee-listeners-many.js
deleted file mode 100644
index bd3f3538d63c92..00000000000000
--- a/benchmark/events/ee-listeners-many.js
+++ /dev/null
@@ -1,22 +0,0 @@
-'use strict';
-const common = require('../common.js');
-const EventEmitter = require('events').EventEmitter;
-
-const bench = common.createBenchmark(main, { n: [5e6] });
-
-function main({ n }) {
- const ee = new EventEmitter();
- ee.setMaxListeners(101);
-
- for (let k = 0; k < 50; k += 1) {
- ee.on('dummy0', () => {});
- ee.on('dummy1', () => {});
- }
-
- bench.start();
- for (let i = 0; i < n; i += 1) {
- const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';
- ee.listeners(dummy);
- }
- bench.end(n);
-}
diff --git a/benchmark/events/ee-listeners.js b/benchmark/events/ee-listeners.js
index 867393efffcb04..9de8d04a175b4b 100644
--- a/benchmark/events/ee-listeners.js
+++ b/benchmark/events/ee-listeners.js
@@ -2,20 +2,34 @@
const common = require('../common.js');
const EventEmitter = require('events').EventEmitter;
-const bench = common.createBenchmark(main, { n: [5e6] });
+const bench = common.createBenchmark(main, {
+ n: [5e6],
+ listeners: [5, 50],
+ raw: ['true', 'false']
+});
-function main({ n }) {
+function main({ n, listeners, raw }) {
const ee = new EventEmitter();
+ ee.setMaxListeners(listeners * 2 + 1);
- for (let k = 0; k < 5; k += 1) {
+ for (let k = 0; k < listeners; k += 1) {
ee.on('dummy0', () => {});
- ee.on('dummy1', () => {});
+ ee.once('dummy1', () => {});
}
- bench.start();
- for (let i = 0; i < n; i += 1) {
- const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';
- ee.listeners(dummy);
+ if (raw === 'true') {
+ bench.start();
+ for (let i = 0; i < n; i += 1) {
+ const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';
+ ee.rawListeners(dummy);
+ }
+ bench.end(n);
+ } else {
+ bench.start();
+ for (let i = 0; i < n; i += 1) {
+ const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';
+ ee.listeners(dummy);
+ }
+ bench.end(n);
}
- bench.end(n);
}
diff --git a/benchmark/events/eventtarget.js b/benchmark/events/eventtarget.js
new file mode 100644
index 00000000000000..d2c3ad034ff9b4
--- /dev/null
+++ b/benchmark/events/eventtarget.js
@@ -0,0 +1,22 @@
+'use strict';
+const common = require('../common.js');
+
+const bench = common.createBenchmark(main, {
+ n: [1e6],
+ listeners: [1, 5, 10]
+}, { flags: ['--expose-internals'] });
+
+function main({ n, listeners }) {
+ const { EventTarget, Event } = require('internal/event_target');
+ const target = new EventTarget();
+
+ for (let n = 0; n < listeners; n++)
+ target.addEventListener('foo', () => {});
+
+ bench.start();
+ for (let i = 0; i < n; i++) {
+ target.dispatchEvent(new Event('foo'));
+ }
+ bench.end(n);
+
+}
diff --git a/benchmark/http/http_server_for_chunky_client.js b/benchmark/http/http_server_for_chunky_client.js
index ef0a23a02928ef..dafaf9122efc86 100644
--- a/benchmark/http/http_server_for_chunky_client.js
+++ b/benchmark/http/http_server_for_chunky_client.js
@@ -10,7 +10,9 @@ process.env.PIPE_NAME = PIPE;
tmpdir.refresh();
-const server = http.createServer((req, res) => {
+// For Node.js versions below v13.3.0 this benchmark will require
+// the flag --max-http-header-size 64000 in order to work properly
+const server = http.createServer({ maxHeaderSize: 64000 }, (req, res) => {
const headers = {
'content-type': 'text/plain',
'content-length': '2'
@@ -28,7 +30,11 @@ const child = fork(
`${__dirname}/_chunky_http_client.js`,
process.argv.slice(2)
);
-child.on('message', common.sendResult);
+child.on('message', (data) => {
+ if (data.type === 'report') {
+ common.sendResult(data);
+ }
+});
child.on('close', (code) => {
server.close();
assert.strictEqual(code, 0);
diff --git a/benchmark/querystring/querystring-stringify.js b/benchmark/querystring/querystring-stringify.js
index be81f67fa826d7..d1b724fcf2c14d 100644
--- a/benchmark/querystring/querystring-stringify.js
+++ b/benchmark/querystring/querystring-stringify.js
@@ -3,7 +3,7 @@ const common = require('../common.js');
const querystring = require('querystring');
const bench = common.createBenchmark(main, {
- type: ['noencode', 'encodemany', 'encodelast', 'array'],
+ type: ['noencode', 'encodemany', 'encodelast', 'array', 'multiprimitives'],
n: [1e6],
});
@@ -28,7 +28,12 @@ function main({ type, n }) {
foo: [],
baz: ['bar'],
xyzzy: ['bar', 'quux', 'thud']
- }
+ },
+ multiprimitives: {
+ foo: false,
+ bar: -13.37,
+ baz: '',
+ },
};
const input = inputs[type];
diff --git a/common.gypi b/common.gypi
index 5e4f9b6dba1dce..9ebda1c4654617 100644
--- a/common.gypi
+++ b/common.gypi
@@ -36,7 +36,7 @@
# 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.33',
+ 'v8_embedder_string': '-node.23',
##### V8 defaults for Node.js #####
@@ -57,6 +57,12 @@
# https://github.com/nodejs/node/pull/22920/files#r222779926
'v8_enable_handle_zapping': 0,
+ # Disable pointer compression. Can be enabled at build time via configure
+ # options but default values are required here as this file is also used by
+ # node-gyp to build addons.
+ 'v8_enable_pointer_compression%': 0,
+ 'v8_enable_31bit_smis_on_64bit_arch%': 0,
+
# Disable V8 untrusted code mitigations.
# See https://github.com/v8/v8/wiki/Untrusted-code-mitigations
'v8_untrusted_code_mitigations': 0,
@@ -193,6 +199,11 @@
],
'msvs_settings': {
'VCCLCompilerTool': {
+ 'conditions': [
+ ['target_arch=="arm64"', {
+ 'FloatingPointModel': 1 # /fp:strict
+ }]
+ ],
'EnableFunctionLevelLinking': 'true',
'EnableIntrinsicFunctions': 'true',
'FavorSizeOrSpeed': 1, # /Ot, favor speed over size
diff --git a/configure b/configure
index 71c2fc87ca4cfc..7e8c4cff832ffd 100755
--- a/configure
+++ b/configure
@@ -5,11 +5,11 @@
# as is the fact that the ] goes on a new line.
_=[ 'exec' '/bin/sh' '-c' '''
test ${FORCE_PYTHON2} && exec python2 "$0" "$@" # workaround for gclient
-which python3.8 >/dev/null && exec python3.8 "$0" "$@"
-which python3.7 >/dev/null && exec python3.7 "$0" "$@"
-which python3.6 >/dev/null && exec python3.6 "$0" "$@"
-which python3.5 >/dev/null && exec python3.5 "$0" "$@"
-which python2.7 >/dev/null && exec python2.7 "$0" "$@"
+command -v python3.8 >/dev/null && exec python3.8 "$0" "$@"
+command -v python3.7 >/dev/null && exec python3.7 "$0" "$@"
+command -v python3.6 >/dev/null && exec python3.6 "$0" "$@"
+command -v python3.5 >/dev/null && exec python3.5 "$0" "$@"
+command -v python2.7 >/dev/null && exec python2.7 "$0" "$@"
exec python "$0" "$@"
''' "$0" "$@"
]
diff --git a/configure.py b/configure.py
index ac26f62916cd06..749692b9e2d69b 100755
--- a/configure.py
+++ b/configure.py
@@ -170,6 +170,11 @@
"e.g. /root/x/y.js will be referenced via require('root/x/y'). "
"Can be used multiple times")
+parser.add_option('--openssl-default-cipher-list',
+ action='store',
+ dest='openssl_default_cipher_list',
+ help='Use the specified cipher list as the default cipher list')
+
parser.add_option("--openssl-no-asm",
action="store_true",
dest="openssl_no_asm",
@@ -646,6 +651,14 @@
default=False,
help='compile V8 with debug checks and runtime debugging features enabled')
+parser.add_option('--v8-lite-mode',
+ action='store_true',
+ dest='v8_lite_mode',
+ default=False,
+ help='compile V8 in lite mode for constrained environments (lowers V8 '+
+ 'memory footprint, but also implies no just-in-time compilation ' +
+ 'support, thus much slower execution)')
+
parser.add_option('--node-builtin-modules-path',
action='store',
dest='node_builtin_modules_path',
@@ -792,7 +805,7 @@ def get_nasm_version(asm):
def get_llvm_version(cc):
return get_version_helper(
- cc, r"(^(?:FreeBSD )?clang version|based on LLVM) ([0-9]+\.[0-9]+)")
+ cc, r"(^(?:.+ )?clang version|based on LLVM) ([0-9]+\.[0-9]+)")
def get_xcode_version(cc):
return get_version_helper(
@@ -999,12 +1012,14 @@ def configure_arm(o):
o['variables']['arm_fpu'] = options.arm_fpu or arm_fpu
-def configure_mips(o):
+def configure_mips(o, target_arch):
can_use_fpu_instructions = (options.mips_float_abi != 'soft')
o['variables']['v8_can_use_fpu_instructions'] = b(can_use_fpu_instructions)
o['variables']['v8_use_mips_abi_hardfloat'] = b(can_use_fpu_instructions)
o['variables']['mips_arch_variant'] = options.mips_arch_variant
o['variables']['mips_fpu_mode'] = options.mips_fpu_mode
+ host_byteorder = 'little' if target_arch in ('mipsel', 'mips64el') else 'big'
+ o['variables']['v8_host_byteorder'] = host_byteorder
def gcc_version_ge(version_checked):
@@ -1041,6 +1056,8 @@ def configure_node(o):
cross_compiling = (options.cross_compiling
if options.cross_compiling is not None
else target_arch != host_arch)
+ if cross_compiling:
+ os.environ['GYP_CROSSCOMPILE'] = "1"
if options.unused_without_snapshot:
warn('building --without-snapshot is no longer possible')
@@ -1062,7 +1079,7 @@ def configure_node(o):
if target_arch == 'arm':
configure_arm(o)
elif target_arch in ('mips', 'mipsel', 'mips64el'):
- configure_mips(o)
+ configure_mips(o, target_arch)
if flavor == 'aix':
o['variables']['node_target_type'] = 'static_library'
@@ -1244,6 +1261,7 @@ def configure_library(lib, output, pkgname=None):
def configure_v8(o):
+ o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
o['variables']['v8_no_strict_aliasing'] = 1 # Work around compiler bugs.
o['variables']['v8_optimized_debug'] = 0 if options.v8_non_optimized_debug else 1
@@ -1291,6 +1309,8 @@ def without_ssl_error(option):
without_ssl_error('--openssl-no-asm')
if options.openssl_fips:
without_ssl_error('--openssl-fips')
+ if options.openssl_default_cipher_list:
+ without_ssl_error('--openssl-default-cipher-list')
return
if options.use_openssl_ca_store:
@@ -1300,6 +1320,9 @@ def without_ssl_error(option):
variables['node_without_node_options'] = b(options.without_node_options)
if options.without_node_options:
o['defines'] += ['NODE_WITHOUT_NODE_OPTIONS']
+ if options.openssl_default_cipher_list:
+ variables['openssl_default_cipher_list'] = \
+ options.openssl_default_cipher_list
if not options.shared_openssl and not options.openssl_no_asm:
is_x86 = 'x64' in variables['target_arch'] or 'ia32' in variables['target_arch']
@@ -1794,6 +1817,10 @@ def make_bin_override():
if options.use_ninja:
config['BUILD_WITH'] = 'ninja'
+# On Windows there is another find.exe in C:\Windows\System32
+if sys.platform == 'win32':
+ config['FIND'] = '/usr/bin/find'
+
config_lines = ['='.join((k,v)) for k,v in config.items()]
# Add a blank string to get a blank line at the end.
config_lines += ['']
diff --git a/deps/icu-small/source/data/in/icudt67l.dat.bz2 b/deps/icu-small/source/data/in/icudt67l.dat.bz2
index 7c63c0bd468f85..60bc3e084f4322 100644
Binary files a/deps/icu-small/source/data/in/icudt67l.dat.bz2 and b/deps/icu-small/source/data/in/icudt67l.dat.bz2 differ
diff --git a/deps/node-inspect/.github/workflows/ci.yml b/deps/node-inspect/.github/workflows/ci.yml
new file mode 100644
index 00000000000000..968316a34779a5
--- /dev/null
+++ b/deps/node-inspect/.github/workflows/ci.yml
@@ -0,0 +1,31 @@
+name: Node CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ node-version:
+ # See https://github.com/nodejs/node-inspect/pull/78
+ # - 10.x
+ - 12.x
+ - 13.x
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: npm install, build, and test
+ run: |
+ npm install
+ npm run build --if-present
+ npm test
+ env:
+ CI: true
diff --git a/deps/node-inspect/lib/_inspect.js b/deps/node-inspect/lib/_inspect.js
index 4d931f7a2bc664..aac278db0a891e 100644
--- a/deps/node-inspect/lib/_inspect.js
+++ b/deps/node-inspect/lib/_inspect.js
@@ -30,15 +30,15 @@ const runAsStandalone = typeof __dirname !== 'undefined';
const [ InspectClient, createRepl ] =
runAsStandalone ?
// This copy of node-inspect is on-disk, relative paths make sense.
- [
- require('./internal/inspect_client'),
- require('./internal/inspect_repl')
- ] :
+ [
+ require('./internal/inspect_client'),
+ require('./internal/inspect_repl')
+ ] :
// This copy of node-inspect is built into the node executable.
- [
- require('node-inspect/lib/internal/inspect_client'),
- require('node-inspect/lib/internal/inspect_repl')
- ];
+ [
+ require('node-inspect/lib/internal/inspect_client'),
+ require('node-inspect/lib/internal/inspect_repl')
+ ];
const debuglog = util.debuglog('inspect');
@@ -49,8 +49,8 @@ class StartupError extends Error {
}
}
-function portIsFree(host, port, timeout = 2000) {
- if (port === 0) return Promise.resolve(); // Binding to a random port.
+function portIsFree(host, port, timeout = 9999) {
+ if (port === 0) return Promise.resolve(); // Binding to a random port.
const retryDelay = 150;
let didTimeOut = false;
@@ -96,9 +96,9 @@ function runScript(script, scriptArgs, inspectHost, inspectPort, childPrint) {
return new Promise((resolve) => {
const needDebugBrk = process.version.match(/^v(6|7)\./);
const args = (needDebugBrk ?
- ['--inspect', `--debug-brk=${inspectPort}`] :
- [`--inspect-brk=${inspectPort}`])
- .concat([script], scriptArgs);
+ ['--inspect', `--debug-brk=${inspectPort}`] :
+ [`--inspect-brk=${inspectPort}`])
+ .concat([script], scriptArgs);
const child = spawn(process.execPath, args);
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
@@ -154,11 +154,11 @@ class NodeInspector {
if (options.script) {
this._runScript = runScript.bind(null,
- options.script,
- options.scriptArgs,
- options.host,
- options.port,
- this.childPrint.bind(this));
+ options.script,
+ options.scriptArgs,
+ options.host,
+ options.port,
+ this.childPrint.bind(this));
} else {
this._runScript =
() => Promise.resolve([null, options.port, options.host]);
@@ -333,8 +333,8 @@ function parseArgv([target, ...args]) {
}
function startInspect(argv = process.argv.slice(2),
- stdin = process.stdin,
- stdout = process.stdout) {
+ stdin = process.stdin,
+ stdout = process.stdout) {
/* eslint-disable no-console */
if (argv.length < 1) {
const invokedAs = runAsStandalone ?
diff --git a/deps/node-inspect/lib/internal/inspect_repl.js b/deps/node-inspect/lib/internal/inspect_repl.js
index d9d3f89f03a408..bfbedf66a71b79 100644
--- a/deps/node-inspect/lib/internal/inspect_repl.js
+++ b/deps/node-inspect/lib/internal/inspect_repl.js
@@ -85,9 +85,16 @@ function extractFunctionName(description) {
return fnNameMatch ? `: ${fnNameMatch[1]}` : '';
}
-const NATIVES = process.binding('natives');
+const PUBLIC_BUILTINS = require('module').builtinModules;
+const NATIVES = PUBLIC_BUILTINS ? process.binding('natives') : {};
function isNativeUrl(url) {
- return url.replace('.js', '') in NATIVES || url === 'bootstrap_node.js';
+ url = url.replace(/\.js$/, '');
+ if (PUBLIC_BUILTINS) {
+ if (url.startsWith('internal/') || PUBLIC_BUILTINS.includes(url))
+ return true;
+ }
+
+ return url in NATIVES || url === 'bootstrap_node';
}
function getRelativePath(filenameOrURL) {
@@ -775,6 +782,14 @@ function createRepl(inspector) {
}
Debugger.on('paused', ({ callFrames, reason /* , hitBreakpoints */ }) => {
+ if (process.env.NODE_INSPECT_RESUME_ON_START === '1' &&
+ reason === 'Break on start') {
+ debuglog('Paused on start, but NODE_INSPECT_RESUME_ON_START' +
+ ' environment variable is set to 1, resuming');
+ inspector.client.callMethod('Debugger.resume');
+ return;
+ }
+
// Save execution context's data
currentBacktrace = Backtrace.from(callFrames);
selectedFrame = currentBacktrace[0];
diff --git a/deps/node-inspect/package.json b/deps/node-inspect/package.json
index c64582703cc6d9..925fb03f21a53d 100644
--- a/deps/node-inspect/package.json
+++ b/deps/node-inspect/package.json
@@ -1,6 +1,6 @@
{
"name": "node-inspect",
- "version": "1.11.6",
+ "version": "2.0.0",
"description": "Node Inspect",
"license": "MIT",
"main": "lib/_inspect.js",
@@ -27,7 +27,7 @@
},
"dependencies": {},
"devDependencies": {
- "eslint": "^3.10.2",
+ "eslint": "^6.8.0",
"nlm": "^3.0.0",
"tap": "^10.7.0"
},
diff --git a/deps/node-inspect/test/cli/address.test.js b/deps/node-inspect/test/cli/address.test.js
new file mode 100644
index 00000000000000..1dbe4f37b42175
--- /dev/null
+++ b/deps/node-inspect/test/cli/address.test.js
@@ -0,0 +1,71 @@
+'use strict';
+const { spawn } = require('child_process');
+const Path = require('path');
+const { test } = require('tap');
+
+const startCLI = require('./start-cli');
+
+// NOTE(oyyd): We might want to import this regexp from "lib/_inspect.js"?
+const kDebuggerMsgReg = /Debugger listening on ws:\/\/\[?(.+?)\]?:(\d+)\//;
+
+function launchTarget(...args) {
+ const childProc = spawn(process.execPath, args);
+ return new Promise((resolve, reject) => {
+ const onExit = () => {
+ reject(new Error('Child process exits unexpectly'));
+ };
+ childProc.on('exit', onExit);
+ childProc.stderr.setEncoding('utf8');
+ childProc.stderr.on('data', (data) => {
+ const ret = kDebuggerMsgReg.exec(data);
+ childProc.removeListener('exit', onExit);
+ if (ret) {
+ resolve({
+ childProc,
+ host: ret[1],
+ port: ret[2],
+ });
+ }
+ });
+ });
+}
+
+// process.debugPort is our proxy for "the version of node used to run this
+// test suite doesn't support SIGUSR1 for enabling --inspect for a process".
+const defaultsToOldProtocol = process.debugPort === 5858;
+
+test('examples/alive.js', { skip: defaultsToOldProtocol }, (t) => {
+ const script = Path.join('examples', 'alive.js');
+ let cli = null;
+ let target = null;
+
+ function cleanup(error) {
+ if (cli) {
+ cli.quit();
+ cli = null;
+ }
+ if (target) {
+ target.kill();
+ target = null;
+ }
+ if (error) throw error;
+ }
+
+ return launchTarget('--inspect=0', script)
+ .then(({ childProc, host, port }) => {
+ target = childProc;
+ cli = startCLI([`${host || '127.0.0.1'}:${port}`]);
+ return cli.waitForPrompt();
+ })
+ .then(() => cli.command('sb("alive.js", 3)'))
+ .then(() => cli.waitFor(/break/))
+ .then(() => cli.waitForPrompt())
+ .then(() => {
+ t.match(
+ cli.output,
+ '> 3 ++x;',
+ 'marks the 3rd line');
+ })
+ .then(() => cleanup())
+ .then(null, cleanup);
+});
diff --git a/deps/node-inspect/test/cli/invalid-args.test.js b/deps/node-inspect/test/cli/invalid-args.test.js
index c1aaeb6a9ce750..86428a3ec27030 100644
--- a/deps/node-inspect/test/cli/invalid-args.test.js
+++ b/deps/node-inspect/test/cli/invalid-args.test.js
@@ -27,7 +27,7 @@ test('launch w/ invalid host:port', (t) => {
});
});
-test('launch w/ unavailable port', async (t) => {
+test('launch w/ unavailable port', async(t) => {
const blocker = createServer((socket) => socket.end());
const port = await new Promise((resolve, reject) => {
blocker.on('error', reject);
diff --git a/deps/node-inspect/test/cli/launch.test.js b/deps/node-inspect/test/cli/launch.test.js
index 087a46c54bb8c6..c4ff3d855a82bc 100644
--- a/deps/node-inspect/test/cli/launch.test.js
+++ b/deps/node-inspect/test/cli/launch.test.js
@@ -174,3 +174,23 @@ test('run after quit / restart', (t) => {
.then(() => cli.quit())
.then(null, onFatal);
});
+
+test('auto-resume on start if the environment variable is defined', (t) => {
+ const script = Path.join('examples', 'break.js');
+
+ const cli = startCLI([script], [], {
+ env: { NODE_INSPECT_RESUME_ON_START: '1' }
+ });
+
+ return cli.waitForInitialBreak()
+ .then(() => {
+ t.match(
+ cli.breakInfo,
+ { filename: script, line: 10 },
+ 'skips to the first breakpoint');
+ })
+ .then(() => cli.quit())
+ .then((code) => {
+ t.equal(code, 0, 'exits with success');
+ });
+});
diff --git a/deps/node-inspect/test/cli/start-cli.js b/deps/node-inspect/test/cli/start-cli.js
index e2fa5fe47c9ebe..32c666c7647c68 100644
--- a/deps/node-inspect/test/cli/start-cli.js
+++ b/deps/node-inspect/test/cli/start-cli.js
@@ -8,8 +8,8 @@ tap.test('startCLI', (t) => t.end());
const CLI =
process.env.USE_EMBEDDED_NODE_INSPECT === '1' ?
- 'inspect' :
- require.resolve('../../cli.js');
+ 'inspect' :
+ require.resolve('../../cli.js');
const BREAK_MESSAGE = new RegExp('(?:' + [
'assert', 'break', 'break on start', 'debugCommand',
@@ -20,8 +20,8 @@ function isPreBreak(output) {
return /Break on start/.test(output) && /1 \(function \(exports/.test(output);
}
-function startCLI(args, flags = []) {
- const child = spawn(process.execPath, [...flags, CLI, ...args]);
+function startCLI(args, flags = [], spawnOpts = {}) {
+ const child = spawn(process.execPath, [...flags, CLI, ...args], spawnOpts);
let isFirstStdoutChunk = true;
const outputBuffer = [];
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index 83370a7bb0efcd..7eb49322af01f2 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -67,6 +67,7 @@ ipch
# Clion / IntelliJ project files
/.idea/
+cmake-build-debug/
*.xcodeproj
*.xcworkspace
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 410d9461ad11d5..222367e41ee06e 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -425,3 +425,10 @@ Sk Sajidul Kadir
twosee
Rikard Falkeborn
Yash Ladha
+James Ross
+Colin Finck
+Shohei YOSHIDA
+Philip Chimento
+Michal Artazov
+Jeroen Roovers
+MasterDuke17
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index c82fa2b56d8771..0496d36ae970a1 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -24,6 +24,12 @@ cmake_dependent_option(LIBUV_BUILD_BENCH
"Build the benchmarks when building unit tests and we are the root project" ON
"LIBUV_BUILD_TESTS" OFF)
+# Qemu Build
+option(QEMU "build for qemu" OFF)
+if(QEMU)
+ add_definitions(-D__QEMU__=1)
+endif()
+
# Compiler check
string(CONCAT is-msvc $,
@@ -31,6 +37,18 @@ string(CONCAT is-msvc $)
check_c_compiler_flag(/W4 UV_LINT_W4)
+check_c_compiler_flag(/wd4100 UV_LINT_NO_UNUSED_PARAMETER_MSVC)
+check_c_compiler_flag(/wd4127 UV_LINT_NO_CONDITIONAL_CONSTANT_MSVC)
+check_c_compiler_flag(/wd4201 UV_LINT_NO_NONSTANDARD_MSVC)
+check_c_compiler_flag(/wd4206 UV_LINT_NO_NONSTANDARD_EMPTY_TU_MSVC)
+check_c_compiler_flag(/wd4210 UV_LINT_NO_NONSTANDARD_FILE_SCOPE_MSVC)
+check_c_compiler_flag(/wd4232 UV_LINT_NO_NONSTANDARD_NONSTATIC_DLIMPORT_MSVC)
+check_c_compiler_flag(/wd4456 UV_LINT_NO_HIDES_LOCAL)
+check_c_compiler_flag(/wd4457 UV_LINT_NO_HIDES_PARAM)
+check_c_compiler_flag(/wd4459 UV_LINT_NO_HIDES_GLOBAL)
+check_c_compiler_flag(/wd4706 UV_LINT_NO_CONDITIONAL_ASSIGNMENT_MSVC)
+check_c_compiler_flag(/wd4996 UV_LINT_NO_UNSAFE_MSVC)
+
check_c_compiler_flag(-Wall UV_LINT_WALL) # DO NOT use this under MSVC
# TODO: Place these into its own function
@@ -38,10 +56,21 @@ check_c_compiler_flag(-Wno-unused-parameter UV_LINT_NO_UNUSED_PARAMETER)
check_c_compiler_flag(-Wstrict-prototypes UV_LINT_STRICT_PROTOTYPES)
check_c_compiler_flag(-Wextra UV_LINT_EXTRA)
-set(lint-no-unused-parameter $<$:-Wno-unused-parameter>)
+set(lint-no-unused-parameter $<$:-Wno-unused-parameter>)
set(lint-strict-prototypes $<$:-Wstrict-prototypes>)
set(lint-extra $<$:-Wextra>)
set(lint-w4 $<$:/W4>)
+set(lint-no-unused-parameter-msvc $<$:/wd4100>)
+set(lint-no-conditional-constant-msvc $<$:/wd4127>)
+set(lint-no-nonstandard-msvc $<$:/wd4201>)
+set(lint-no-nonstandard-empty-tu-msvc $<$:/wd4206>)
+set(lint-no-nonstandard-file-scope-msvc $<$:/wd4210>)
+set(lint-no-nonstandard-nonstatic-dlimport-msvc $<$:/wd4232>)
+set(lint-no-hides-local-msvc $<$:/wd4456>)
+set(lint-no-hides-param-msvc $<$:/wd4457>)
+set(lint-no-hides-global-msvc $<$:/wd4459>)
+set(lint-no-conditional-assignment-msvc $<$:/wd4706>)
+set(lint-no-unsafe-msvc $<$:/wd4996>)
# Unfortunately, this one is complicated because MSVC and clang-cl support -Wall
# but using it is like calling -Weverything
string(CONCAT lint-default $<
@@ -50,6 +79,17 @@ string(CONCAT lint-default $<
list(APPEND uv_cflags ${lint-strict-prototypes} ${lint-extra} ${lint-default} ${lint-w4})
list(APPEND uv_cflags ${lint-no-unused-parameter})
+list(APPEND uv_cflags ${lint-no-unused-parameter-msvc})
+list(APPEND uv_cflags ${lint-no-conditional-constant-msvc})
+list(APPEND uv_cflags ${lint-no-nonstandard-msvc})
+list(APPEND uv_cflags ${lint-no-nonstandard-empty-tu-msvc})
+list(APPEND uv_cflags ${lint-no-nonstandard-file-scope-msvc})
+list(APPEND uv_cflags ${lint-no-nonstandard-nonstatic-dlimport-msvc})
+list(APPEND uv_cflags ${lint-no-hides-local-msvc})
+list(APPEND uv_cflags ${lint-no-hides-param-msvc})
+list(APPEND uv_cflags ${lint-no-hides-global-msvc})
+list(APPEND uv_cflags ${lint-no-conditional-assignment-msvc})
+list(APPEND uv_cflags ${lint-no-unsafe-msvc})
set(uv_sources
src/fs-poll.c
@@ -64,22 +104,9 @@ set(uv_sources
src/version.c)
if(WIN32)
- if (CMAKE_SYSTEM_VERSION VERSION_GREATER 10) # Windows 10
- set(windows-version 0x0A00)
- elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.3) # Windows 8.1
- set(windows-version 0x0603)
- elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.2) # Windows 8
- set(windows-version 0x0602)
- elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.1) # Windows 7
- set(windows-version 0x0601)
- elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.0) # Windows Vista
- set(windows-version 0x0600)
- else()
- message(FATAL_ERROR "Windows Vista is the minimum version supported")
- endif()
- list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=${windows-version})
+ list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0600)
list(APPEND uv_libraries
- $<$:psapi>
+ psapi
iphlpapi
userenv
ws2_32)
@@ -155,7 +182,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
- list(APPEND uv_libs dl)
+ list(APPEND uv_libraries dl)
list(APPEND uv_sources
src/unix/android-ifaddrs.c
src/unix/linux-core.c
@@ -489,7 +516,7 @@ if(LIBUV_BUILD_TESTS)
test/test-walk-handles.c
test/test-watcher-cross-stop.c)
- add_executable(uv_run_tests ${uv_test_sources})
+ add_executable(uv_run_tests ${uv_test_sources} uv_win_longpath.manifest)
target_compile_definitions(uv_run_tests
PRIVATE ${uv_defines} USING_UV_SHARED=1)
target_compile_options(uv_run_tests PRIVATE ${uv_cflags})
@@ -501,10 +528,14 @@ if(LIBUV_BUILD_TESTS)
set_tests_properties(uv_test PROPERTIES ENVIRONMENT
"LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}")
endif()
- add_executable(uv_run_tests_a ${uv_test_sources})
+ add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest)
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
- target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries})
+ if(QEMU)
+ target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries} -static)
+ else()
+ target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries})
+ endif()
add_test(NAME uv_test_a
COMMAND uv_run_tests_a
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
@@ -544,3 +575,11 @@ if(WIN32)
RUNTIME DESTINATION lib/$
ARCHIVE DESTINATION lib/$)
endif()
+
+message(STATUS "summary of build options:
+ Install prefix: ${CMAKE_INSTALL_PREFIX}
+ Target system: ${CMAKE_SYSTEM_NAME}
+ Compiler:
+ C compiler: ${CMAKE_C_COMPILER}
+ CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
+")
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 3544c6c01b5a31..9b215a5ba0f6b9 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,76 @@
+2020.05.18, Version 1.38.0 (Stable), 1ab9ea3790378f9f25c4e78e9e2b511c75f9c9ed
+
+Changes since version 1.37.0:
+
+* test: skip poll_duplex and poll_unidirectional on PASE (Xu Meng)
+
+* linux: make cpu_times consistently be milliseconds (James Ross)
+
+* win: DRY uv_poll_start() and uv_poll_stop() (Ben Noordhuis)
+
+* win: DRY uv_poll_close() (Ben Noordhuis)
+
+* unix,win: add uv_library_shutdown() (Ben Noordhuis)
+
+* unix: yield cpu when spinlocking on async handle (Ben Noordhuis)
+
+* win: remove dep on GetQueuedCompletionStatusEx (Colin Finck)
+
+* doc: correct source lines (Shohei YOSHIDA)
+
+* build,android: fix typo (twosee)
+
+* doc: uv_cancel() handles uv_random_t requests (Philip Chimento)
+
+* doc: fix unescaped character (Philip Chimento)
+
+* build,cmake: fix compilation on old MinGW (erw7)
+
+* build: remove unnessesary MSVC warnings (Bartosz Sosnowski)
+
+* win: make uv_udp_init_ex() accept UV_UDP_RECVMMSG (Ben Noordhuis)
+
+* unix: simplify uv__udp_init_ex() (Ben Noordhuis)
+
+* win: remove MAX_PATH limitations (Bartosz Sosnowski)
+
+* build, win: add long path aware manifest (Bartosz Sosnowski)
+
+* doc: check/idle/prepare functions always succeed (Ben Noordhuis)
+
+* darwin: fix build with non-apple compilers (Ben Noordhuis)
+
+* win: support environment variables > 32767 chars (Ben Noordhuis)
+
+* unix: fully initialize struct msghdr (Ben Noordhuis)
+
+* doc: add uv_replace_allocator thread safety warning (twosee)
+
+* unix: fix int overflow when copying large files (Michal Artazov)
+
+* fs: report original error (Bartosz Sosnowski)
+
+* win, fs: add IO_REPARSE_TAG_APPEXECLINK support (Bartosz Sosnowski)
+
+* doc: fix formatting (Ben Noordhuis)
+
+* unix: fix memory leak when uv_loop_init() fails (Anna Henningsen)
+
+* unix: shrink uv_udp_set_source_membership() stack (Ben Noordhuis)
+
+* unix,win: fix wrong sizeof argument to memcpy() (Ben Noordhuis)
+
+* build: check for libraries not provided by libc (Jeroen Roovers)
+
+* doc: fix the order of arguments to calloc() (MasterDuke17)
+
+* unix: don't abort when getrlimit() fails (Ben Noordhuis)
+
+* test: support common user profile on IBMi (Xu Meng)
+
+* build: test on more platforms via QEMU in CI (gengjiawen)
+
+
2020.04.20, Version 1.37.0 (Stable), 02a9e1be252b623ee032a3137c0b0c94afbe6809
Changes since version 1.36.0:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 23fa19dc4fc8e7..d9d2f3d02f52b4 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -409,8 +409,9 @@ uvinclude_HEADERS += include/uv/darwin.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
- src/unix/darwin.c \
src/unix/darwin-proctitle.c \
+ src/unix/darwin-stub.h \
+ src/unix/darwin.c \
src/unix/fsevents.c \
src/unix/kqueue.c \
src/unix/proctitle.c \
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index cd7bab08570c8f..6616972ab1b98d 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [1.37.0], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.38.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
@@ -38,15 +38,17 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
LT_INIT
-# TODO(bnoordhuis) Check for -pthread vs. -pthreads
+AX_PTHREAD([
+ LIBS="$LIBS $PTHREAD_LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+])
AC_CHECK_LIB([dl], [dlopen])
-AC_CHECK_LIB([kstat], [kstat_lookup])
-AC_CHECK_LIB([nsl], [gethostbyname])
-AC_CHECK_LIB([perfstat], [perfstat_cpu])
-AC_CHECK_LIB([pthread], [pthread_mutex_init])
-AC_CHECK_LIB([rt], [clock_gettime])
-AC_CHECK_LIB([sendfile], [sendfile])
-AC_CHECK_LIB([socket], [socket])
+AC_SEARCH_LIBS([kstat_lookup], [kstat])
+AC_SEARCH_LIBS([gethostbyname], [nsl])
+AC_SEARCH_LIBS([perfstat_cpu], [perfstat])
+AC_SEARCH_LIBS([clock_gettime], [rt])
+AC_SEARCH_LIBS([sendfile], [sendfile])
+AC_SEARCH_LIBS([socket], [socket])
AC_SYS_LARGEFILE
AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])
diff --git a/deps/uv/docs/src/check.rst b/deps/uv/docs/src/check.rst
index 36c93cf03d99c0..33aab5516c2649 100644
--- a/deps/uv/docs/src/check.rst
+++ b/deps/uv/docs/src/check.rst
@@ -33,14 +33,22 @@ API
.. c:function:: int uv_check_init(uv_loop_t* loop, uv_check_t* check)
- Initialize the handle.
+ Initialize the handle. This function always succeeds.
+
+ :returns: 0
.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb)
- Start the handle with the given callback.
+ Start the handle with the given callback. This function always succeeds,
+ except when `cb` is `NULL`.
+
+ :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_check_stop(uv_check_t* check)
Stop the handle, the callback will no longer be called.
+ This function always succeeds.
+
+ :returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index a475a460307898..73666f3cd87c29 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -492,6 +492,13 @@ API
.. versionadded:: 1.19.0
+.. c:function:: int uv_fs_get_system_error(const uv_fs_t* req)
+
+ Returns the platform specific error code - `GetLastError()` value on Windows
+ and `-(req->result)` on other platforms.
+
+ .. versionadded:: 1.38.0
+
.. c:function:: void* uv_fs_get_ptr(const uv_fs_t* req)
Returns `req->ptr`.
diff --git a/deps/uv/docs/src/idle.rst b/deps/uv/docs/src/idle.rst
index 1f51c4a19e4a0b..b7a0507b0de2ac 100644
--- a/deps/uv/docs/src/idle.rst
+++ b/deps/uv/docs/src/idle.rst
@@ -41,14 +41,22 @@ API
.. c:function:: int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle)
- Initialize the handle.
+ Initialize the handle. This function always succeeds.
+
+ :returns: 0
.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
- Start the handle with the given callback.
+ Start the handle with the given callback. This function always succeeds,
+ except when `cb` is `NULL`.
+
+ :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_idle_stop(uv_idle_t* idle)
Stop the handle, the callback will no longer be called.
+ This function always succeeds.
+
+ :returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 8515cdbc1b040a..906ca8ff75d345 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -131,11 +131,11 @@ Data types
char* model;
int speed;
struct uv_cpu_times_s {
- uint64_t user;
- uint64_t nice;
- uint64_t sys;
- uint64_t idle;
- uint64_t irq;
+ uint64_t user; /* milliseconds */
+ uint64_t nice; /* milliseconds */
+ uint64_t sys; /* milliseconds */
+ uint64_t idle; /* milliseconds */
+ uint64_t irq; /* milliseconds */
} cpu_times;
} uv_cpu_info_t;
@@ -233,6 +233,24 @@ API
sure the allocator is changed while no memory was allocated with
the previous allocator, or that they are compatible.
+ .. warning:: Allocator must be thread-safe.
+
+.. c:function:: void uv_library_shutdown(void);
+
+ .. versionadded:: 1.38.0
+
+ Release any global state that libuv is holding onto. Libuv will normally
+ do so automatically when it is unloaded but it can be instructed to perform
+ cleanup manually.
+
+ .. warning:: Only call :c:func:`uv_library_shutdown()` once.
+
+ .. warning:: Don't call :c:func:`uv_library_shutdown()` when there are
+ still event loops or I/O requests active.
+
+ .. warning:: Don't call libuv functions after calling
+ :c:func:`uv_library_shutdown()`.
+
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
Constructor for :c:type:`uv_buf_t`.
@@ -657,7 +675,7 @@ API
.. note::
On IBM i PASE, you are not allowed to change your priority unless you
- have the *JOBCTL special authority (even to lower it).
+ have the \*JOBCTL special authority (even to lower it).
.. versionadded:: 1.23.0
diff --git a/deps/uv/docs/src/prepare.rst b/deps/uv/docs/src/prepare.rst
index aca58155809cd9..5e0d247660ee14 100644
--- a/deps/uv/docs/src/prepare.rst
+++ b/deps/uv/docs/src/prepare.rst
@@ -33,14 +33,22 @@ API
.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare)
- Initialize the handle.
+ Initialize the handle. This function always succeeds.
+
+ :returns: 0
.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb)
- Start the handle with the given callback.
+ Start the handle with the given callback. This function always succeeds,
+ except when `cb` is `NULL`.
+
+ :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare)
Stop the handle, the callback will no longer be called.
+ This function always succeeds.
+
+ :returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/request.rst b/deps/uv/docs/src/request.rst
index 56038287b2ae11..5807ccba4a748e 100644
--- a/deps/uv/docs/src/request.rst
+++ b/deps/uv/docs/src/request.rst
@@ -69,8 +69,8 @@ API
Returns 0 on success, or an error code < 0 on failure.
Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`,
- :c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is
- currently supported.
+ :c:type:`uv_getnameinfo_t`, :c:type:`uv_random_t` and :c:type:`uv_work_t`
+ requests is currently supported.
Cancelled requests have their callbacks invoked some time in the future.
It's **not** safe to free the memory associated with the request until the
@@ -80,8 +80,9 @@ API
* A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`.
- * A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t`
- request has its callback invoked with status == `UV_ECANCELED`.
+ * A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t`,
+ :c:type:`uv_getnameinfo_t` or :c:type:`uv_random_t` request has its
+ callback invoked with status == `UV_ECANCELED`.
.. c:function:: size_t uv_req_size(uv_req_type type)
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index a3a770db88b90e..fec663136a4ff1 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -265,6 +265,8 @@ typedef void* (*uv_realloc_func)(void* ptr, size_t size);
typedef void* (*uv_calloc_func)(size_t count, size_t size);
typedef void (*uv_free_func)(void* ptr);
+UV_EXTERN void uv_library_shutdown(void);
+
UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
uv_realloc_func realloc_func,
uv_calloc_func calloc_func,
@@ -1069,11 +1071,11 @@ UV_EXTERN int uv_cancel(uv_req_t* req);
struct uv_cpu_times_s {
- uint64_t user;
- uint64_t nice;
- uint64_t sys;
- uint64_t idle;
- uint64_t irq;
+ uint64_t user; /* milliseconds */
+ uint64_t nice; /* milliseconds */
+ uint64_t sys; /* milliseconds */
+ uint64_t idle; /* milliseconds */
+ uint64_t irq; /* milliseconds */
};
struct uv_cpu_info_s {
@@ -1305,6 +1307,7 @@ struct uv_fs_s {
UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*);
UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*);
+UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*);
UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*);
UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*);
UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*);
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index be97adf6fff794..486658c3933982 100644
--- a/deps/uv/include/uv/version.h
+++ b/deps/uv/include/uv/version.h
@@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 37
+#define UV_VERSION_MINOR 38
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c
index a8f433f0510800..0998938f3e0d16 100644
--- a/deps/uv/src/threadpool.c
+++ b/deps/uv/src/threadpool.c
@@ -160,8 +160,8 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
}
+void uv__threadpool_cleanup(void) {
#ifndef _WIN32
-UV_DESTRUCTOR(static void cleanup(void)) {
unsigned int i;
if (nthreads == 0)
@@ -181,8 +181,8 @@ UV_DESTRUCTOR(static void cleanup(void)) {
threads = NULL;
nthreads = 0;
-}
#endif
+}
static void init_threads(void) {
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 417ee5512fa252..6b4594b43e9777 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -926,7 +926,7 @@ int uv_get_process_title(char* buffer, size_t size) {
}
-UV_DESTRUCTOR(static void free_args_mem(void)) {
+void uv__process_title_cleanup(void) {
uv__free(args_mem); /* Keep valgrind happy. */
args_mem = NULL;
}
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
index 26d337e0a44c0e..5f58fb88d628ec 100644
--- a/deps/uv/src/unix/async.c
+++ b/deps/uv/src/unix/async.c
@@ -32,6 +32,7 @@
#include
#include
#include
+#include /* sched_yield() */
#ifdef __linux__
#include
@@ -81,20 +82,32 @@ int uv_async_send(uv_async_t* handle) {
/* Only call this from the event loop thread. */
static int uv__async_spin(uv_async_t* handle) {
+ int i;
int rc;
for (;;) {
- /* rc=0 -- handle is not pending.
- * rc=1 -- handle is pending, other thread is still working with it.
- * rc=2 -- handle is pending, other thread is done.
+ /* 997 is not completely chosen at random. It's a prime number, acyclical
+ * by nature, and should therefore hopefully dampen sympathetic resonance.
*/
- rc = cmpxchgi(&handle->pending, 2, 0);
-
- if (rc != 1)
- return rc;
-
- /* Other thread is busy with this handle, spin until it's done. */
- cpu_relax();
+ for (i = 0; i < 997; i++) {
+ /* rc=0 -- handle is not pending.
+ * rc=1 -- handle is pending, other thread is still working with it.
+ * rc=2 -- handle is pending, other thread is done.
+ */
+ rc = cmpxchgi(&handle->pending, 2, 0);
+
+ if (rc != 1)
+ return rc;
+
+ /* Other thread is busy with this handle, spin until it's done. */
+ cpu_relax();
+ }
+
+ /* Yield the CPU. We may have preempted the other thread while it's
+ * inside the critical section and if it's running on the same CPU
+ * as us, we'll just burn CPU cycles until the end of our time slice.
+ */
+ sched_yield();
}
}
diff --git a/deps/uv/src/unix/bsd-proctitle.c b/deps/uv/src/unix/bsd-proctitle.c
index 0ce47c8f64e25d..723b81c01c201f 100644
--- a/deps/uv/src/unix/bsd-proctitle.c
+++ b/deps/uv/src/unix/bsd-proctitle.c
@@ -37,6 +37,13 @@ static void init_process_title_mutex_once(void) {
}
+void uv__process_title_cleanup(void) {
+ /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex)
+ * and reset process_title_mutex_once?
+ */
+}
+
+
char** uv_setup_args(int argc, char** argv) {
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
return argv;
diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c
index 2daf3e3474acff..5288083ef04fd7 100644
--- a/deps/uv/src/unix/darwin-proctitle.c
+++ b/deps/uv/src/unix/darwin-proctitle.c
@@ -30,8 +30,7 @@
#include
#if !TARGET_OS_IPHONE
-# include
-# include
+#include "darwin-stub.h"
#endif
diff --git a/deps/uv/src/unix/darwin-stub.h b/deps/uv/src/unix/darwin-stub.h
new file mode 100644
index 00000000000000..b93cf67c596285
--- /dev/null
+++ b/deps/uv/src/unix/darwin-stub.h
@@ -0,0 +1,97 @@
+/* Copyright libuv project contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_DARWIN_STUB_H_
+#define UV_DARWIN_STUB_H_
+
+#include
+
+struct CFArrayCallBacks;
+struct CFRunLoopSourceContext;
+struct FSEventStreamContext;
+
+typedef double CFAbsoluteTime;
+typedef double CFTimeInterval;
+typedef int FSEventStreamEventFlags;
+typedef int OSStatus;
+typedef long CFIndex;
+typedef struct CFArrayCallBacks CFArrayCallBacks;
+typedef struct CFRunLoopSourceContext CFRunLoopSourceContext;
+typedef struct FSEventStreamContext FSEventStreamContext;
+typedef uint32_t FSEventStreamCreateFlags;
+typedef uint64_t FSEventStreamEventId;
+typedef unsigned CFStringEncoding;
+typedef void* CFAllocatorRef;
+typedef void* CFArrayRef;
+typedef void* CFBundleRef;
+typedef void* CFDictionaryRef;
+typedef void* CFRunLoopRef;
+typedef void* CFRunLoopSourceRef;
+typedef void* CFStringRef;
+typedef void* CFTypeRef;
+typedef void* FSEventStreamRef;
+
+typedef void (*FSEventStreamCallback)(const FSEventStreamRef,
+ void*,
+ size_t,
+ void*,
+ const FSEventStreamEventFlags*,
+ const FSEventStreamEventId*);
+
+struct CFRunLoopSourceContext {
+ CFIndex version;
+ void* info;
+ void* pad[7];
+ void (*perform)(void*);
+};
+
+struct FSEventStreamContext {
+ CFIndex version;
+ void* info;
+ void* pad[3];
+};
+
+static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100;
+static const OSStatus noErr = 0;
+
+static const FSEventStreamEventId kFSEventStreamEventIdSinceNow = -1;
+
+static const int kFSEventStreamCreateFlagNoDefer = 2;
+static const int kFSEventStreamCreateFlagFileEvents = 16;
+
+static const int kFSEventStreamEventFlagEventIdsWrapped = 8;
+static const int kFSEventStreamEventFlagHistoryDone = 16;
+static const int kFSEventStreamEventFlagItemChangeOwner = 0x4000;
+static const int kFSEventStreamEventFlagItemCreated = 0x100;
+static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x2000;
+static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x400;
+static const int kFSEventStreamEventFlagItemIsDir = 0x20000;
+static const int kFSEventStreamEventFlagItemModified = 0x1000;
+static const int kFSEventStreamEventFlagItemRemoved = 0x200;
+static const int kFSEventStreamEventFlagItemRenamed = 0x800;
+static const int kFSEventStreamEventFlagItemXattrMod = 0x8000;
+static const int kFSEventStreamEventFlagKernelDropped = 4;
+static const int kFSEventStreamEventFlagMount = 64;
+static const int kFSEventStreamEventFlagRootChanged = 32;
+static const int kFSEventStreamEventFlagUnmount = 128;
+static const int kFSEventStreamEventFlagUserDropped = 2;
+
+#endif /* UV_DARWIN_STUB_H_ */
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 1b8d2ad199662b..f5b2b94207c19c 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -1110,9 +1110,10 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
int dst_flags;
int result;
int err;
- size_t bytes_to_send;
- int64_t in_offset;
- ssize_t bytes_written;
+ off_t bytes_to_send;
+ off_t in_offset;
+ off_t bytes_written;
+ size_t bytes_chunk;
dstfd = -1;
err = 0;
@@ -1211,7 +1212,10 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
bytes_to_send = src_statsbuf.st_size;
in_offset = 0;
while (bytes_to_send != 0) {
- uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_to_send, NULL);
+ bytes_chunk = SSIZE_MAX;
+ if (bytes_to_send < (off_t) bytes_chunk)
+ bytes_chunk = bytes_to_send;
+ uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_chunk, NULL);
bytes_written = fs_req.result;
uv_fs_req_cleanup(&fs_req);
@@ -2082,3 +2086,7 @@ int uv_fs_statfs(uv_loop_t* loop,
PATH;
POST;
}
+
+int uv_fs_get_system_error(const uv_fs_t* req) {
+ return -req->result;
+}
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index 448921f813d789..a51f29b3f6db55 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -41,34 +41,33 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
#else /* TARGET_OS_IPHONE */
+#include "darwin-stub.h"
+
#include
#include
#include
#include
-#include
-#include
-
-/* These are macros to avoid "initializer element is not constant" errors
- * with old versions of gcc.
- */
-#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod | \
- kFSEventStreamEventFlagItemModified | \
- kFSEventStreamEventFlagItemInodeMetaMod | \
- kFSEventStreamEventFlagItemChangeOwner | \
- kFSEventStreamEventFlagItemXattrMod)
-
-#define kFSEventsRenamed (kFSEventStreamEventFlagItemCreated | \
- kFSEventStreamEventFlagItemRemoved | \
- kFSEventStreamEventFlagItemRenamed)
-
-#define kFSEventsSystem (kFSEventStreamEventFlagUserDropped | \
- kFSEventStreamEventFlagKernelDropped | \
- kFSEventStreamEventFlagEventIdsWrapped | \
- kFSEventStreamEventFlagHistoryDone | \
- kFSEventStreamEventFlagMount | \
- kFSEventStreamEventFlagUnmount | \
- kFSEventStreamEventFlagRootChanged)
+static const int kFSEventsModified =
+ kFSEventStreamEventFlagItemChangeOwner |
+ kFSEventStreamEventFlagItemFinderInfoMod |
+ kFSEventStreamEventFlagItemInodeMetaMod |
+ kFSEventStreamEventFlagItemModified |
+ kFSEventStreamEventFlagItemXattrMod;
+
+static const int kFSEventsRenamed =
+ kFSEventStreamEventFlagItemCreated |
+ kFSEventStreamEventFlagItemRemoved |
+ kFSEventStreamEventFlagItemRenamed;
+
+static const int kFSEventsSystem =
+ kFSEventStreamEventFlagUserDropped |
+ kFSEventStreamEventFlagKernelDropped |
+ kFSEventStreamEventFlagEventIdsWrapped |
+ kFSEventStreamEventFlagHistoryDone |
+ kFSEventStreamEventFlagMount |
+ kFSEventStreamEventFlagUnmount |
+ kFSEventStreamEventFlagRootChanged;
typedef struct uv__fsevents_event_s uv__fsevents_event_t;
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
@@ -148,7 +147,7 @@ static void (*pFSEventStreamRelease)(FSEventStreamRef);
static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef,
CFRunLoopRef,
CFStringRef);
-static Boolean (*pFSEventStreamStart)(FSEventStreamRef);
+static int (*pFSEventStreamStart)(FSEventStreamRef);
static void (*pFSEventStreamStop)(FSEventStreamRef);
#define UV__FSEVENTS_PROCESS(handle, block) \
@@ -215,7 +214,7 @@ static void uv__fsevents_push_event(uv_fs_event_t* handle,
/* Runs in CF thread, when there're events in FSEventStream */
-static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
+static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
void* info,
size_t numEvents,
void* eventPaths,
@@ -340,11 +339,8 @@ static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
FSEventStreamCreateFlags flags;
/* Initialize context */
- ctx.version = 0;
+ memset(&ctx, 0, sizeof(ctx));
ctx.info = loop;
- ctx.retain = NULL;
- ctx.release = NULL;
- ctx.copyDescription = NULL;
latency = 0.05;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 598554b607ec42..402ee877d076b6 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -106,10 +106,8 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
#if defined(__clang__) || \
defined(__GNUC__) || \
defined(__INTEL_COMPILER)
-# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
#else
-# define UV_DESTRUCTOR(declaration) declaration
# define UV_UNUSED(declaration) declaration
#endif
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index f8d9ff5868ab58..99cbb1c8fd7ea4 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -768,7 +768,8 @@ static int read_times(FILE* statfile_fp,
unsigned int numcpus,
uv_cpu_info_t* ci) {
struct uv_cpu_times_s ts;
- uint64_t clock_ticks;
+ unsigned int ticks;
+ unsigned int multiplier;
uint64_t user;
uint64_t nice;
uint64_t sys;
@@ -779,9 +780,10 @@ static int read_times(FILE* statfile_fp,
uint64_t len;
char buf[1024];
- clock_ticks = sysconf(_SC_CLK_TCK);
- assert(clock_ticks != (uint64_t) -1);
- assert(clock_ticks != 0);
+ ticks = (unsigned int)sysconf(_SC_CLK_TCK);
+ multiplier = ((uint64_t)1000L / ticks);
+ assert(ticks != (unsigned int) -1);
+ assert(ticks != 0);
rewind(statfile_fp);
@@ -823,11 +825,11 @@ static int read_times(FILE* statfile_fp,
&irq))
abort();
- ts.user = clock_ticks * user;
- ts.nice = clock_ticks * nice;
- ts.sys = clock_ticks * sys;
- ts.idle = clock_ticks * idle;
- ts.irq = clock_ticks * irq;
+ ts.user = user * multiplier;
+ ts.nice = nice * multiplier;
+ ts.sys = sys * multiplier;
+ ts.idle = idle * multiplier;
+ ts.irq = irq * multiplier;
ci[num++].cpu_times = ts;
}
assert(num == numcpus);
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
index c2a03d770f3764..e5b2889560a516 100644
--- a/deps/uv/src/unix/loop.c
+++ b/deps/uv/src/unix/loop.c
@@ -106,6 +106,8 @@ int uv_loop_init(uv_loop_t* loop) {
fail_signal_init:
uv__platform_loop_delete(loop);
+ uv__free(loop->watchers);
+ loop->nwatchers = 0;
return err;
}
diff --git a/deps/uv/src/unix/no-proctitle.c b/deps/uv/src/unix/no-proctitle.c
index 165740ca3ff9d5..32aa0af1f92f07 100644
--- a/deps/uv/src/unix/no-proctitle.c
+++ b/deps/uv/src/unix/no-proctitle.c
@@ -29,6 +29,9 @@ char** uv_setup_args(int argc, char** argv) {
return argv;
}
+void uv__process_title_cleanup(void) {
+}
+
int uv_set_process_title(const char* title) {
return 0;
}
diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c
index d124d3c7fcfee0..4ee991fcc32466 100644
--- a/deps/uv/src/unix/proctitle.c
+++ b/deps/uv/src/unix/proctitle.c
@@ -145,7 +145,7 @@ int uv_get_process_title(char* buffer, size_t size) {
}
-UV_DESTRUCTOR(static void free_args_mem(void)) {
+void uv__process_title_cleanup(void) {
uv__free(args_mem); /* Keep valgrind happy. */
args_mem = NULL;
}
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index 1e7e8ac574dfa4..1c83e095bcdead 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -77,7 +77,7 @@ static void uv__signal_global_init(void) {
}
-UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
+void uv__signal_cleanup(void) {
/* We can only use signal-safe functions here.
* That includes read/write and close, fortunately.
* We do all of this directly here instead of resetting
@@ -98,7 +98,7 @@ UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
static void uv__signal_global_reinit(void) {
- uv__signal_global_fini();
+ uv__signal_cleanup();
if (uv__make_pipe(uv__signal_lock_pipefd, 0))
abort();
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index f10c351ebba27a..c9a18d1e8d440a 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -172,10 +172,11 @@ static size_t thread_stack_size(void) {
#if defined(__APPLE__) || defined(__linux__)
struct rlimit lim;
- if (getrlimit(RLIMIT_STACK, &lim))
- abort();
-
- if (lim.rlim_cur != RLIM_INFINITY) {
+ /* getrlimit() can fail on some aarch64 systems due to a glibc bug where
+ * the system call wrapper invokes the wrong system call. Don't treat
+ * that as fatal, just use the default stack size instead.
+ */
+ if (0 == getrlimit(RLIMIT_STACK, &lim) && lim.rlim_cur != RLIM_INFINITY) {
/* pthread_attr_setstacksize() expects page-aligned values. */
lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize();
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 3aa11c5beeb4ad..7cf80ef3b9f648 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -42,6 +42,11 @@
# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
+union uv__sockaddr {
+ struct sockaddr_in6 in6;
+ struct sockaddr_in in;
+ struct sockaddr addr;
+};
static void uv__udp_run_completed(uv_udp_t* handle);
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
@@ -202,6 +207,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
msgs[k].msg_hdr.msg_iovlen = 1;
msgs[k].msg_hdr.msg_name = peers + k;
msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]);
+ msgs[k].msg_hdr.msg_control = NULL;
+ msgs[k].msg_hdr.msg_controllen = 0;
+ msgs[k].msg_hdr.msg_flags = 0;
}
do
@@ -564,11 +572,7 @@ int uv__udp_bind(uv_udp_t* handle,
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
int domain,
unsigned int flags) {
- union {
- struct sockaddr_in6 in6;
- struct sockaddr_in in;
- struct sockaddr addr;
- } taddr;
+ union uv__sockaddr taddr;
socklen_t addrlen;
if (handle->io_watcher.fd != -1)
@@ -921,8 +925,10 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
mreq.gsr_interface = 0;
}
- memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
- memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
+ STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
+ STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
+ memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
+ memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
if (membership == UV_JOIN_GROUP)
optname = MCAST_JOIN_SOURCE_GROUP;
@@ -944,29 +950,17 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
#endif
-int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
- int domain;
- int err;
- int extra_flags;
+int uv__udp_init_ex(uv_loop_t* loop,
+ uv_udp_t* handle,
+ unsigned flags,
+ int domain) {
int fd;
- /* Use the lower 8 bits for the domain */
- domain = flags & 0xFF;
- if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
- return UV_EINVAL;
-
- /* Use the higher bits for extra flags */
- extra_flags = flags & ~0xFF;
- if (extra_flags & ~UV_UDP_RECVMMSG)
- return UV_EINVAL;
-
+ fd = -1;
if (domain != AF_UNSPEC) {
- err = uv__socket(domain, SOCK_DGRAM, 0);
- if (err < 0)
- return err;
- fd = err;
- } else {
- fd = -1;
+ fd = uv__socket(domain, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return fd;
}
uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
@@ -978,18 +972,10 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
QUEUE_INIT(&handle->write_queue);
QUEUE_INIT(&handle->write_completed_queue);
- if (extra_flags & UV_UDP_RECVMMSG)
- handle->flags |= UV_HANDLE_UDP_RECVMMSG;
-
return 0;
}
-int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
- return uv_udp_init_ex(loop, handle, AF_UNSPEC);
-}
-
-
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int err;
@@ -1047,40 +1033,31 @@ int uv_udp_set_source_membership(uv_udp_t* handle,
uv_membership membership) {
#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
int err;
- struct sockaddr_storage mcast_addr;
- struct sockaddr_in* mcast_addr4;
- struct sockaddr_in6* mcast_addr6;
- struct sockaddr_storage src_addr;
- struct sockaddr_in* src_addr4;
- struct sockaddr_in6* src_addr6;
-
- mcast_addr4 = (struct sockaddr_in*)&mcast_addr;
- mcast_addr6 = (struct sockaddr_in6*)&mcast_addr;
- src_addr4 = (struct sockaddr_in*)&src_addr;
- src_addr6 = (struct sockaddr_in6*)&src_addr;
-
- err = uv_ip4_addr(multicast_addr, 0, mcast_addr4);
+ union uv__sockaddr mcast_addr;
+ union uv__sockaddr src_addr;
+
+ err = uv_ip4_addr(multicast_addr, 0, &mcast_addr.in);
if (err) {
- err = uv_ip6_addr(multicast_addr, 0, mcast_addr6);
+ err = uv_ip6_addr(multicast_addr, 0, &mcast_addr.in6);
if (err)
return err;
- err = uv_ip6_addr(source_addr, 0, src_addr6);
+ err = uv_ip6_addr(source_addr, 0, &src_addr.in6);
if (err)
return err;
return uv__udp_set_source_membership6(handle,
- mcast_addr6,
+ &mcast_addr.in6,
interface_addr,
- src_addr6,
+ &src_addr.in6,
membership);
}
- err = uv_ip4_addr(source_addr, 0, src_addr4);
+ err = uv_ip4_addr(source_addr, 0, &src_addr.in);
if (err)
return err;
return uv__udp_set_source_membership4(handle,
- mcast_addr4,
+ &mcast_addr.in,
interface_addr,
- src_addr4,
+ &src_addr.in,
membership);
#else
return UV_ENOSYS;
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 5cb1a8c898f7ae..a25d6aaef7217f 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -293,6 +293,36 @@ int uv_tcp_bind(uv_tcp_t* handle,
}
+int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) {
+ unsigned extra_flags;
+ int domain;
+ int rc;
+
+ /* Use the lower 8 bits for the domain. */
+ domain = flags & 0xFF;
+ if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
+ return UV_EINVAL;
+
+ /* Use the higher bits for extra flags. */
+ extra_flags = flags & ~0xFF;
+ if (extra_flags & ~UV_UDP_RECVMMSG)
+ return UV_EINVAL;
+
+ rc = uv__udp_init_ex(loop, handle, flags, domain);
+
+ if (rc == 0)
+ if (extra_flags & UV_UDP_RECVMMSG)
+ handle->flags |= UV_HANDLE_UDP_RECVMMSG;
+
+ return rc;
+}
+
+
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+ return uv_udp_init_ex(loop, handle, AF_UNSPEC);
+}
+
+
int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int flags) {
@@ -821,3 +851,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
uv__free(cpu_infos);
}
+
+
+#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
+__attribute__((destructor))
+#endif
+void uv_library_shutdown(void) {
+ static int was_shutdown;
+
+ if (was_shutdown)
+ return;
+
+ uv__process_title_cleanup();
+ uv__signal_cleanup();
+ uv__threadpool_cleanup();
+ was_shutdown = 1;
+}
diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
index f08fb8ae091e72..0b0f5f86a01a12 100644
--- a/deps/uv/src/uv-common.h
+++ b/deps/uv/src/uv-common.h
@@ -139,6 +139,11 @@ int uv__tcp_connect(uv_connect_t* req,
unsigned int addrlen,
uv_connect_cb cb);
+int uv__udp_init_ex(uv_loop_t* loop,
+ uv_udp_t* handle,
+ unsigned flags,
+ int domain);
+
int uv__udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int addrlen,
@@ -201,6 +206,10 @@ int uv__next_timeout(const uv_loop_t* loop);
void uv__run_timers(uv_loop_t* loop);
void uv__timer_close(uv_timer_t* handle);
+void uv__process_title_cleanup(void);
+void uv__signal_cleanup(void);
+void uv__threadpool_cleanup(void);
+
#define uv__has_active_reqs(loop) \
((loop)->active_reqs.count > 0)
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index 6ded90cdcc7f86..9974a115534320 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -449,12 +449,12 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) {
- success = GetQueuedCompletionStatusEx(loop->iocp,
- overlappeds,
- ARRAY_SIZE(overlappeds),
- &count,
- timeout,
- FALSE);
+ success = pGetQueuedCompletionStatusEx(loop->iocp,
+ overlappeds,
+ ARRAY_SIZE(overlappeds),
+ &count,
+ timeout,
+ FALSE);
if (success) {
for (i = 0; i < count; i++) {
diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c
index 32ac5e596fea82..3ec984c83eb077 100644
--- a/deps/uv/src/win/error.c
+++ b/deps/uv/src/win/error.c
@@ -72,6 +72,7 @@ int uv_translate_sys_error(int sys_errno) {
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ELEVATION_REQUIRED: return UV_EACCES;
+ case ERROR_CANT_ACCESS_FILE: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
case WSAEADDRINUSE: return UV_EADDRINUSE;
case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index acf8e1107e9786..0126c5ededf376 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -83,6 +83,7 @@ static void uv_relative_path(const WCHAR* filename,
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
WCHAR** file) {
size_t len, i;
+ DWORD dir_len;
if (filename == NULL) {
if (dir != NULL)
@@ -97,12 +98,16 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
if (i == 0) {
if (dir) {
- *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
+ dir_len = GetCurrentDirectoryW(0, NULL);
+ if (dir_len == 0) {
+ return -1;
+ }
+ *dir = (WCHAR*)uv__malloc(dir_len * sizeof(WCHAR));
if (!*dir) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
+ if (!GetCurrentDirectoryW(dir_len, *dir)) {
uv__free(*dir);
*dir = NULL;
return -1;
@@ -155,9 +160,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
int name_size, is_path_dir, size;
DWORD attr, last_error;
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
- WCHAR short_path_buffer[MAX_PATH];
+ DWORD short_path_buffer_len;
+ WCHAR *short_path_buffer;
WCHAR* short_path, *long_path;
+ short_path = NULL;
if (uv__is_active(handle))
return UV_EINVAL;
@@ -230,13 +237,23 @@ int uv_fs_event_start(uv_fs_event_t* handle,
*/
/* Convert to short path. */
+ short_path_buffer = NULL;
+ short_path_buffer_len = GetShortPathNameW(pathw, NULL, 0);
+ if (short_path_buffer_len == 0) {
+ goto short_path_done;
+ }
+ short_path_buffer = uv__malloc(short_path_buffer_len * sizeof(WCHAR));
+ if (short_path_buffer == NULL) {
+ goto short_path_done;
+ }
if (GetShortPathNameW(pathw,
short_path_buffer,
- ARRAY_SIZE(short_path_buffer))) {
- short_path = short_path_buffer;
- } else {
- short_path = NULL;
+ short_path_buffer_len) == 0) {
+ uv__free(short_path_buffer);
+ short_path_buffer = NULL;
}
+short_path_done:
+ short_path = short_path_buffer;
if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
last_error = GetLastError();
@@ -346,6 +363,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (uv__is_active(handle))
uv__handle_stop(handle);
+ uv__free(short_path);
+
return uv_translate_sys_error(last_error);
}
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 834c44a26d44cb..9577bc02d3cf24 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -257,6 +257,7 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
req->loop = loop;
req->flags = 0;
req->fs_type = fs_type;
+ req->sys_errno_ = 0;
req->result = 0;
req->ptr = NULL;
req->path = NULL;
@@ -321,6 +322,8 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
WCHAR* w_target;
DWORD w_target_len;
DWORD bytes;
+ size_t i;
+ size_t len;
if (!DeviceIoControl(handle,
FSCTL_GET_REPARSE_POINT,
@@ -405,6 +408,38 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
w_target += 4;
w_target_len -= 4;
+ } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) {
+ /* String #3 in the list has the target filename. */
+ if (reparse_data->AppExecLinkReparseBuffer.StringCount < 3) {
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+ w_target = reparse_data->AppExecLinkReparseBuffer.StringList;
+ /* The StringList buffer contains a list of strings separated by "\0", */
+ /* with "\0\0" terminating the list. Move to the 3rd string in the list: */
+ for (i = 0; i < 2; ++i) {
+ len = wcslen(w_target);
+ if (len == 0) {
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+ w_target += len + 1;
+ }
+ w_target_len = wcslen(w_target);
+ if (w_target_len == 0) {
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+ /* Make sure it is an absolute path. */
+ if (!(w_target_len >= 3 &&
+ ((w_target[0] >= L'a' && w_target[0] <= L'z') ||
+ (w_target[0] >= L'A' && w_target[0] <= L'Z')) &&
+ w_target[1] == L':' &&
+ w_target[2] == L'\\')) {
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+
} else {
/* Reparse tag does not indicate a symlink. */
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
@@ -2840,7 +2875,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
INIT(UV_FS_OPEN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.info.file_flags = flags;
@@ -2865,8 +2901,10 @@ int uv_fs_read(uv_loop_t* loop,
uv_fs_cb cb) {
INIT(UV_FS_READ);
- if (bufs == NULL || nbufs == 0)
+ if (bufs == NULL || nbufs == 0) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
+ }
req->file.fd = fd;
@@ -2875,8 +2913,10 @@ int uv_fs_read(uv_loop_t* loop,
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
- if (req->fs.info.bufs == NULL)
+ if (req->fs.info.bufs == NULL) {
+ SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return UV_ENOMEM;
+ }
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
@@ -2894,8 +2934,10 @@ int uv_fs_write(uv_loop_t* loop,
uv_fs_cb cb) {
INIT(UV_FS_WRITE);
- if (bufs == NULL || nbufs == 0)
+ if (bufs == NULL || nbufs == 0) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
+ }
req->file.fd = fd;
@@ -2904,8 +2946,10 @@ int uv_fs_write(uv_loop_t* loop,
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
- if (req->fs.info.bufs == NULL)
+ if (req->fs.info.bufs == NULL) {
+ SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return UV_ENOMEM;
+ }
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
@@ -2921,7 +2965,8 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_UNLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -2935,7 +2980,8 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
INIT(UV_FS_MKDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.info.mode = mode;
@@ -2951,8 +2997,10 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
INIT(UV_FS_MKDTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
POST;
}
@@ -2966,8 +3014,10 @@ int uv_fs_mkstemp(uv_loop_t* loop,
INIT(UV_FS_MKSTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
POST;
}
@@ -2979,7 +3029,8 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_RMDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -2993,7 +3044,8 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
INIT(UV_FS_SCANDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.info.file_flags = flags;
@@ -3008,8 +3060,10 @@ int uv_fs_opendir(uv_loop_t* loop,
INIT(UV_FS_OPENDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
POST;
}
@@ -3022,6 +3076,7 @@ int uv_fs_readdir(uv_loop_t* loop,
if (dir == NULL ||
dir->dirents == NULL ||
dir->dir_handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
@@ -3034,8 +3089,10 @@ int uv_fs_closedir(uv_loop_t* loop,
uv_dir_t* dir,
uv_fs_cb cb) {
INIT(UV_FS_CLOSEDIR);
- if (dir == NULL)
+ if (dir == NULL) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
+ }
req->ptr = dir;
POST;
}
@@ -3047,7 +3104,8 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_LINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3061,7 +3119,8 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_SYMLINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.info.file_flags = flags;
@@ -3076,7 +3135,8 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_READLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3090,12 +3150,14 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_REALPATH);
if (!path) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3109,7 +3171,8 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
INIT(UV_FS_CHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3130,8 +3193,10 @@ int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
INIT(UV_FS_LCHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
+
POST;
}
@@ -3142,7 +3207,8 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_STAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3155,7 +3221,8 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_LSTAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3176,7 +3243,8 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_RENAME);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
POST;
@@ -3219,13 +3287,15 @@ int uv_fs_copyfile(uv_loop_t* loop,
if (flags & ~(UV_FS_COPYFILE_EXCL |
UV_FS_COPYFILE_FICLONE |
UV_FS_COPYFILE_FICLONE_FORCE)) {
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
err = fs__capture_path(req, path, new_path, cb != NULL);
-
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
req->fs.info.file_flags = flags;
POST;
@@ -3252,8 +3322,10 @@ int uv_fs_access(uv_loop_t* loop,
INIT(UV_FS_ACCESS);
err = fs__capture_path(req, path, NULL, cb != NULL);
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
req->fs.info.mode = flags;
POST;
@@ -3267,7 +3339,8 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
INIT(UV_FS_CHMOD);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.info.mode = mode;
@@ -3291,7 +3364,8 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
INIT(UV_FS_UTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.time.atime = atime;
@@ -3316,7 +3390,8 @@ int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
INIT(UV_FS_LUTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
- return uv_translate_sys_error(err);
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
}
req->fs.time.atime = atime;
@@ -3333,8 +3408,14 @@ int uv_fs_statfs(uv_loop_t* loop,
INIT(UV_FS_STATFS);
err = fs__capture_path(req, path, NULL, cb != NULL);
- if (err)
- return uv_translate_sys_error(err);
+ if (err) {
+ SET_REQ_WIN32_ERROR(req, err);
+ return req->result;
+ }
POST;
}
+
+int uv_fs_get_system_error(const uv_fs_t* req) {
+ return req->sys_errno_;
+}
diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c
index 3c6678600e40cc..87858590c8525a 100644
--- a/deps/uv/src/win/poll.c
+++ b/deps/uv/src/win/poll.c
@@ -134,32 +134,6 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
}
-static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
- AFD_POLL_INFO afd_poll_info;
- int result;
-
- afd_poll_info.Exclusive = TRUE;
- afd_poll_info.NumberOfHandles = 1;
- afd_poll_info.Timeout.QuadPart = INT64_MAX;
- afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
- afd_poll_info.Handles[0].Status = 0;
- afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
-
- result = uv_msafd_poll(handle->socket,
- &afd_poll_info,
- uv__get_afd_poll_info_dummy(),
- uv__get_overlapped_dummy());
-
- if (result == SOCKET_ERROR) {
- DWORD error = WSAGetLastError();
- if (error != WSA_IO_PENDING)
- return error;
- }
-
- return 0;
-}
-
-
static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
uv_req_t* req) {
unsigned char mask_events;
@@ -226,44 +200,6 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
-static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
- assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV_HANDLE_CLOSING));
- assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
-
- handle->events = events;
-
- if (handle->events != 0) {
- uv__handle_start(handle);
- } else {
- uv__handle_stop(handle);
- }
-
- if ((handle->events & ~(handle->submitted_events_1 |
- handle->submitted_events_2)) != 0) {
- uv__fast_poll_submit_poll_req(handle->loop, handle);
- }
-
- return 0;
-}
-
-
-static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
- handle->events = 0;
- uv__handle_closing(handle);
-
- if (handle->submitted_events_1 == 0 &&
- handle->submitted_events_2 == 0) {
- uv_want_endgame(loop, (uv_handle_t*) handle);
- return 0;
- } else {
- /* Cancel outstanding poll requests by executing another, unique poll
- * request that forces the outstanding ones to return. */
- return uv__fast_poll_cancel_poll_req(loop, handle);
- }
-}
-
-
static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
WSAPROTOCOL_INFOW* protocol_info) {
SOCKET sock = 0;
@@ -469,41 +405,6 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
-static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
- assert(handle->type == UV_POLL);
- assert(!(handle->flags & UV_HANDLE_CLOSING));
- assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
-
- handle->events = events;
-
- if (handle->events != 0) {
- uv__handle_start(handle);
- } else {
- uv__handle_stop(handle);
- }
-
- if ((handle->events &
- ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
- uv__slow_poll_submit_poll_req(handle->loop, handle);
- }
-
- return 0;
-}
-
-
-static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
- handle->events = 0;
- uv__handle_closing(handle);
-
- if (handle->submitted_events_1 == 0 &&
- handle->submitted_events_2 == 0) {
- uv_want_endgame(loop, (uv_handle_t*) handle);
- }
-
- return 0;
-}
-
-
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
}
@@ -582,35 +483,43 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
}
-int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
- int err;
+static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) {
+ int submitted_events;
- if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
- err = uv__fast_poll_set(handle->loop, handle, events);
- } else {
- err = uv__slow_poll_set(handle->loop, handle, events);
- }
+ assert(handle->type == UV_POLL);
+ assert(!(handle->flags & UV_HANDLE_CLOSING));
+ assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
+
+ handle->events = events;
+ handle->poll_cb = cb;
- if (err) {
- return uv_translate_sys_error(err);
+ if (handle->events == 0) {
+ uv__handle_stop(handle);
+ return 0;
}
- handle->poll_cb = cb;
+ uv__handle_start(handle);
+ submitted_events = handle->submitted_events_1 | handle->submitted_events_2;
+
+ if (handle->events & ~submitted_events) {
+ if (handle->flags & UV_HANDLE_POLL_SLOW) {
+ uv__slow_poll_submit_poll_req(handle->loop, handle);
+ } else {
+ uv__fast_poll_submit_poll_req(handle->loop, handle);
+ }
+ }
return 0;
}
-int uv_poll_stop(uv_poll_t* handle) {
- int err;
+int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
+ return uv__poll_set(handle, events, cb);
+}
- if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
- err = uv__fast_poll_set(handle->loop, handle, 0);
- } else {
- err = uv__slow_poll_set(handle->loop, handle, 0);
- }
- return uv_translate_sys_error(err);
+int uv_poll_stop(uv_poll_t* handle) {
+ return uv__poll_set(handle, 0, handle->poll_cb);
}
@@ -624,11 +533,43 @@ void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) {
int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
- if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
- return uv__fast_poll_close(loop, handle);
- } else {
- return uv__slow_poll_close(loop, handle);
+ AFD_POLL_INFO afd_poll_info;
+ DWORD error;
+ int result;
+
+ handle->events = 0;
+ uv__handle_closing(handle);
+
+ if (handle->submitted_events_1 == 0 &&
+ handle->submitted_events_2 == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ return 0;
+ }
+
+ if (handle->flags & UV_HANDLE_POLL_SLOW)
+ return 0;
+
+ /* Cancel outstanding poll requests by executing another, unique poll
+ * request that forces the outstanding ones to return. */
+ afd_poll_info.Exclusive = TRUE;
+ afd_poll_info.NumberOfHandles = 1;
+ afd_poll_info.Timeout.QuadPart = INT64_MAX;
+ afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
+ afd_poll_info.Handles[0].Status = 0;
+ afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
+
+ result = uv_msafd_poll(handle->socket,
+ &afd_poll_info,
+ uv__get_afd_poll_info_dummy(),
+ uv__get_overlapped_dummy());
+
+ if (result == SOCKET_ERROR) {
+ error = WSAGetLastError();
+ if (error != WSA_IO_PENDING)
+ return uv_translate_sys_error(error);
}
+
+ return 0;
}
diff --git a/deps/uv/src/win/signal.c b/deps/uv/src/win/signal.c
index 276dc609733320..3d9f92cfb17017 100644
--- a/deps/uv/src/win/signal.c
+++ b/deps/uv/src/win/signal.c
@@ -46,6 +46,11 @@ void uv_signals_init(void) {
}
+void uv__signal_cleanup(void) {
+ /* TODO(bnoordhuis) Undo effects of uv_signal_init()? */
+}
+
+
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
/* Compare signums first so all watchers with the same signnum end up
* adjacent. */
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 3daa55f62db063..1c4977af968a46 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -125,17 +125,10 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
}
-int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
- int domain;
-
- /* Use the lower 8 bits for the domain */
- domain = flags & 0xFF;
- if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
- return UV_EINVAL;
-
- if (flags & ~0xFF)
- return UV_EINVAL;
-
+int uv__udp_init_ex(uv_loop_t* loop,
+ uv_udp_t* handle,
+ unsigned flags,
+ int domain) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
@@ -174,11 +167,6 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
}
-int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
- return uv_udp_init_ex(loop, handle, AF_UNSPEC);
-}
-
-
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
uv_udp_recv_stop(handle);
closesocket(handle->socket);
@@ -786,8 +774,10 @@ int uv__udp_set_source_membership6(uv_udp_t* handle,
mreq.gsr_interface = 0;
}
- memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
- memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
+ STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
+ STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
+ memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
+ memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
if (membership == UV_JOIN_GROUP)
optname = MCAST_JOIN_SOURCE_GROUP;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index aaa7ba0325b0e5..9e1e7f73e3168b 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -60,9 +60,6 @@
#endif
-/* Maximum environment variable size, including the terminating null */
-#define MAX_ENV_VAR_LENGTH 32767
-
/* A RtlGenRandom() by any other name... */
extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
@@ -154,20 +151,26 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
int uv_cwd(char* buffer, size_t* size) {
DWORD utf16_len;
- WCHAR utf16_buffer[MAX_PATH];
+ WCHAR *utf16_buffer;
int r;
if (buffer == NULL || size == NULL) {
return UV_EINVAL;
}
- utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+ utf16_len = GetCurrentDirectoryW(0, NULL);
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
- } else if (utf16_len > MAX_PATH) {
- /* This should be impossible; however the CRT has a code path to deal with
- * this scenario, so I added a check anyway. */
- return UV_EIO;
+ }
+ utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
+ if (utf16_buffer == NULL) {
+ return UV_ENOMEM;
+ }
+
+ utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
+ if (utf16_len == 0) {
+ uv__free(utf16_buffer);
+ return uv_translate_sys_error(GetLastError());
}
/* utf16_len contains the length, *not* including the terminating null. */
@@ -191,8 +194,10 @@ int uv_cwd(char* buffer, size_t* size) {
NULL,
NULL);
if (r == 0) {
+ uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
} else if (r > (int) *size) {
+ uv__free(utf16_buffer);
*size = r;
return UV_ENOBUFS;
}
@@ -206,6 +211,8 @@ int uv_cwd(char* buffer, size_t* size) {
*size > INT_MAX ? INT_MAX : (int) *size,
NULL,
NULL);
+ uv__free(utf16_buffer);
+
if (r == 0) {
return uv_translate_sys_error(GetLastError());
}
@@ -216,43 +223,61 @@ int uv_cwd(char* buffer, size_t* size) {
int uv_chdir(const char* dir) {
- WCHAR utf16_buffer[MAX_PATH];
- size_t utf16_len;
+ WCHAR *utf16_buffer;
+ size_t utf16_len, new_utf16_len;
WCHAR drive_letter, env_var[4];
if (dir == NULL) {
return UV_EINVAL;
}
+ utf16_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ dir,
+ -1,
+ NULL,
+ 0);
+ if (utf16_len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+ utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
+ if (utf16_buffer == NULL) {
+ return UV_ENOMEM;
+ }
+
if (MultiByteToWideChar(CP_UTF8,
0,
dir,
-1,
utf16_buffer,
- MAX_PATH) == 0) {
- DWORD error = GetLastError();
- /* The maximum length of the current working directory is 260 chars,
- * including terminating null. If it doesn't fit, the path name must be too
- * long. */
- if (error == ERROR_INSUFFICIENT_BUFFER) {
- return UV_ENAMETOOLONG;
- } else {
- return uv_translate_sys_error(error);
- }
+ utf16_len) == 0) {
+ uv__free(utf16_buffer);
+ return uv_translate_sys_error(GetLastError());
}
if (!SetCurrentDirectoryW(utf16_buffer)) {
+ uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
}
/* Windows stores the drive-local path in an "hidden" environment variable,
* which has the form "=C:=C:\Windows". SetCurrentDirectory does not update
* this, so we'll have to do it. */
- utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+ new_utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
+ if (new_utf16_len > utf16_len ) {
+ uv__free(utf16_buffer);
+ utf16_buffer = uv__malloc(new_utf16_len * sizeof(WCHAR));
+ if (utf16_buffer == NULL) {
+ /* When updating the environment variable fails, return UV_OK anyway.
+ * We did successfully change current working directory, only updating
+ * hidden env variable failed. */
+ return 0;
+ }
+ new_utf16_len = GetCurrentDirectoryW(new_utf16_len, utf16_buffer);
+ }
if (utf16_len == 0) {
- return uv_translate_sys_error(GetLastError());
- } else if (utf16_len > MAX_PATH) {
- return UV_EIO;
+ uv__free(utf16_buffer);
+ return 0;
}
/* The returned directory should not have a trailing slash, unless it points
@@ -284,11 +309,10 @@ int uv_chdir(const char* dir) {
env_var[2] = L':';
env_var[3] = L'\0';
- if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
- return uv_translate_sys_error(GetLastError());
- }
+ SetEnvironmentVariableW(env_var, utf16_buffer);
}
+ uv__free(utf16_buffer);
return 0;
}
@@ -361,6 +385,10 @@ char** uv_setup_args(int argc, char** argv) {
}
+void uv__process_title_cleanup(void) {
+}
+
+
int uv_set_process_title(const char* title) {
int err;
int length;
@@ -1163,20 +1191,29 @@ int uv_os_homedir(char* buffer, size_t* size) {
int uv_os_tmpdir(char* buffer, size_t* size) {
- wchar_t path[MAX_PATH + 2];
+ wchar_t *path;
DWORD bufsize;
size_t len;
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
- len = GetTempPathW(ARRAY_SIZE(path), path);
+ len = 0;
+ len = GetTempPathW(0, NULL);
+ if (len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+ /* Include space for terminating null char. */
+ len += 1;
+ path = uv__malloc(len * sizeof(wchar_t));
+ if (path == NULL) {
+ return UV_ENOMEM;
+ }
+ len = GetTempPathW(len, path);
if (len == 0) {
+ uv__free(path);
return uv_translate_sys_error(GetLastError());
- } else if (len > ARRAY_SIZE(path)) {
- /* This should not be possible */
- return UV_EIO;
}
/* The returned directory should not have a trailing slash, unless it points
@@ -1191,8 +1228,10 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
+ uv__free(path);
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
+ uv__free(path);
*size = bufsize;
return UV_ENOBUFS;
}
@@ -1206,6 +1245,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
*size,
NULL,
NULL);
+ uv__free(path);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
@@ -1325,7 +1365,7 @@ int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
int uv__getpwuid_r(uv_passwd_t* pwd) {
HANDLE token;
wchar_t username[UNLEN + 1];
- wchar_t path[MAX_PATH];
+ wchar_t *path;
DWORD bufsize;
int r;
@@ -1336,15 +1376,24 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
return uv_translate_sys_error(GetLastError());
- bufsize = ARRAY_SIZE(path);
- if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+ bufsize = 0;
+ GetUserProfileDirectoryW(token, NULL, &bufsize);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
r = GetLastError();
CloseHandle(token);
+ return uv_translate_sys_error(r);
+ }
- /* This should not be possible */
- if (r == ERROR_INSUFFICIENT_BUFFER)
- return UV_ENOMEM;
+ path = uv__malloc(bufsize * sizeof(wchar_t));
+ if (path == NULL) {
+ CloseHandle(token);
+ return UV_ENOMEM;
+ }
+ if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+ r = GetLastError();
+ CloseHandle(token);
+ uv__free(path);
return uv_translate_sys_error(r);
}
@@ -1354,6 +1403,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
bufsize = ARRAY_SIZE(username);
if (!GetUserNameW(username, &bufsize)) {
r = GetLastError();
+ uv__free(path);
/* This should not be possible */
if (r == ERROR_INSUFFICIENT_BUFFER)
@@ -1364,6 +1414,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
pwd->homedir = NULL;
r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
+ uv__free(path);
if (r != 0)
return r;
@@ -1461,7 +1512,9 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
- wchar_t var[MAX_ENV_VAR_LENGTH];
+ wchar_t fastvar[512];
+ wchar_t* var;
+ DWORD varlen;
wchar_t* name_w;
DWORD bufsize;
size_t len;
@@ -1475,25 +1528,52 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
if (r != 0)
return r;
- SetLastError(ERROR_SUCCESS);
- len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
+ var = fastvar;
+ varlen = ARRAY_SIZE(fastvar);
+
+ for (;;) {
+ SetLastError(ERROR_SUCCESS);
+ len = GetEnvironmentVariableW(name_w, var, varlen);
+
+ if (len < varlen)
+ break;
+
+ /* Try repeatedly because we might have been preempted by another thread
+ * modifying the environment variable just as we're trying to read it.
+ */
+ if (var != fastvar)
+ uv__free(var);
+
+ varlen = 1 + len;
+ var = uv__malloc(varlen * sizeof(*var));
+
+ if (var == NULL) {
+ r = UV_ENOMEM;
+ goto fail;
+ }
+ }
+
uv__free(name_w);
- assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
+ name_w = NULL;
if (len == 0) {
r = GetLastError();
- if (r != ERROR_SUCCESS)
- return uv_translate_sys_error(r);
+ if (r != ERROR_SUCCESS) {
+ r = uv_translate_sys_error(r);
+ goto fail;
+ }
}
/* Check how much space we need */
bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
- return uv_translate_sys_error(GetLastError());
+ r = uv_translate_sys_error(GetLastError());
+ goto fail;
} else if (bufsize > *size) {
*size = bufsize;
- return UV_ENOBUFS;
+ r = UV_ENOBUFS;
+ goto fail;
}
/* Convert to UTF-8 */
@@ -1506,11 +1586,23 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
NULL,
NULL);
- if (bufsize == 0)
- return uv_translate_sys_error(GetLastError());
+ if (bufsize == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto fail;
+ }
*size = bufsize - 1;
- return 0;
+ r = 0;
+
+fail:
+
+ if (name_w != NULL)
+ uv__free(name_w);
+
+ if (var != fastvar)
+ uv__free(var);
+
+ return r;
}
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 322a212dd73c19..cbe1437a42e6bd 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4152,6 +4152,10 @@ typedef const UNICODE_STRING *PCUNICODE_STRING;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
+ struct {
+ ULONG StringCount;
+ WCHAR StringList[1];
+ } AppExecLinkReparseBuffer;
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#endif
@@ -4517,6 +4521,9 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
#ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
+#ifndef IO_REPARSE_TAG_APPEXECLINK
+# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
+#endif
typedef VOID (NTAPI *PIO_APC_ROUTINE)
(PVOID ApcContext,
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 27b731032e10b3..e95e3bde5a7e3e 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -230,6 +230,7 @@ typedef enum {
do { \
close_loop(uv_default_loop()); \
ASSERT(0 == uv_loop_close(uv_default_loop())); \
+ uv_library_shutdown(); \
} while (0)
/* Just sugar for wrapping the main() for a task or helper. */
diff --git a/deps/uv/test/test-connection-fail.c b/deps/uv/test/test-connection-fail.c
index 8338cacdec3c5f..5904810252995f 100644
--- a/deps/uv/test/test-connection-fail.c
+++ b/deps/uv/test/test-connection-fail.c
@@ -120,6 +120,11 @@ static void connection_fail(uv_connect_cb connect_cb) {
* expect an error.
*/
TEST_IMPL(connection_fail) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
connection_fail(on_connect_with_close);
ASSERT(timer_close_cb_calls == 0);
@@ -136,6 +141,11 @@ TEST_IMPL(connection_fail) {
* attempt.
*/
TEST_IMPL(connection_fail_doesnt_auto_close) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
int r;
r = uv_timer_init(uv_default_loop(), &timer);
diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c
index f61c1c6c115cae..ecaba337ca1088 100644
--- a/deps/uv/test/test-env-vars.c
+++ b/deps/uv/test/test-env-vars.c
@@ -142,5 +142,29 @@ TEST_IMPL(env_vars) {
r = uv_os_unsetenv(name2);
ASSERT(r == 0);
+ for (i = 1; i <= 4; i++) {
+ size_t n;
+ char* p;
+
+ n = i * 32768;
+ size = n + 1;
+
+ p = malloc(size);
+ ASSERT_NOT_NULL(p);
+
+ memset(p, 'x', n);
+ p[n] = '\0';
+
+ ASSERT_EQ(0, uv_os_setenv(name, p));
+ ASSERT_EQ(0, uv_os_getenv(name, p, &size));
+ ASSERT_EQ(n, size);
+
+ for (n = 0; n < size; n++)
+ ASSERT_EQ('x', p[n]);
+
+ ASSERT_EQ(0, uv_os_unsetenv(name));
+ free(p);
+ }
+
return 0;
}
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 2966a53b79d349..ae9923a9a16ec3 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -315,7 +315,7 @@ static void chown_root_cb(uv_fs_t* req) {
* User may grant qsecofr's privileges, including changing
* the file's ownership to uid 0.
*/
- ASSERT(req->result == 0);
+ ASSERT(req->result == 0 || req->result == UV_EPERM);
# else
ASSERT(req->result == UV_EPERM);
# endif
@@ -2453,6 +2453,57 @@ TEST_IMPL(fs_non_symlink_reparse_point) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+TEST_IMPL(fs_lstat_windows_store_apps) {
+ uv_loop_t* loop;
+ char localappdata[MAX_PATH];
+ char windowsapps_path[MAX_PATH];
+ char file_path[MAX_PATH];
+ size_t len;
+ int r;
+ uv_fs_t req;
+ uv_fs_t stat_req;
+ uv_dirent_t dirent;
+
+ loop = uv_default_loop();
+ ASSERT_NOT_NULL(loop);
+ len = sizeof(localappdata);
+ r = uv_os_getenv("LOCALAPPDATA", localappdata, &len);
+ if (r == UV_ENOENT) {
+ MAKE_VALGRIND_HAPPY();
+ return TEST_SKIP;
+ }
+ ASSERT_EQ(r, 0);
+ r = snprintf(windowsapps_path,
+ sizeof(localappdata),
+ "%s\\Microsoft\\WindowsApps",
+ localappdata);
+ ASSERT_GT(r, 0);
+ if (uv_fs_opendir(loop, &req, windowsapps_path, NULL) != 0) {
+ /* If we cannot read the directory, skip the test. */
+ MAKE_VALGRIND_HAPPY();
+ return TEST_SKIP;
+ }
+ if (uv_fs_scandir(loop, &req, windowsapps_path, 0, NULL) <= 0) {
+ MAKE_VALGRIND_HAPPY();
+ return TEST_SKIP;
+ }
+ while (uv_fs_scandir_next(&req, &dirent) != UV_EOF) {
+ if (dirent.type != UV_DIRENT_LINK) {
+ continue;
+ }
+ if (snprintf(file_path,
+ sizeof(file_path),
+ "%s\\%s",
+ windowsapps_path,
+ dirent.name) < 0) {
+ continue;
+ }
+ ASSERT_EQ(uv_fs_lstat(loop, &stat_req, file_path, NULL), 0);
+ }
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
#endif
@@ -4347,3 +4398,21 @@ TEST_IMPL(fs_statfs) {
return 0;
}
+
+TEST_IMPL(fs_get_system_error) {
+ uv_fs_t req;
+ int r;
+ int system_error;
+
+ r = uv_fs_statfs(NULL, &req, "non_existing_file", NULL);
+ ASSERT(r != 0);
+
+ system_error = uv_fs_get_system_error(&req);
+#ifdef _WIN32
+ ASSERT(system_error == ERROR_FILE_NOT_FOUND);
+#else
+ ASSERT(system_error == ENOENT);
+#endif
+
+ return 0;
+}
diff --git a/deps/uv/test/test-get-currentexe.c b/deps/uv/test/test-get-currentexe.c
index 8c730334c205b3..5e4a083f3060b7 100644
--- a/deps/uv/test/test-get-currentexe.c
+++ b/deps/uv/test/test-get-currentexe.c
@@ -31,6 +31,11 @@
extern char executable_path[];
TEST_IMPL(get_currentexe) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
char buffer[PATHMAX];
char path[PATHMAX];
size_t size;
diff --git a/deps/uv/test/test-get-passwd.c b/deps/uv/test/test-get-passwd.c
index 9b5273b315db6f..abe8be36a332b5 100644
--- a/deps/uv/test/test-get-passwd.c
+++ b/deps/uv/test/test-get-passwd.c
@@ -24,6 +24,11 @@
#include
TEST_IMPL(get_passwd) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
uv_passwd_t pwd;
size_t len;
int r;
diff --git a/deps/uv/test/test-getaddrinfo.c b/deps/uv/test/test-getaddrinfo.c
index 03dc126956162c..f2b4e03cd74cdb 100644
--- a/deps/uv/test/test-getaddrinfo.c
+++ b/deps/uv/test/test-getaddrinfo.c
@@ -106,6 +106,10 @@ TEST_IMPL(getaddrinfo_fail) {
TEST_IMPL(getaddrinfo_fail_sync) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
uv_getaddrinfo_t req;
/* Use a FQDN by ending in a period */
@@ -144,6 +148,10 @@ TEST_IMPL(getaddrinfo_basic) {
TEST_IMPL(getaddrinfo_basic_sync) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
uv_getaddrinfo_t req;
ASSERT(0 == uv_getaddrinfo(uv_default_loop(),
diff --git a/deps/uv/test/test-getnameinfo.c b/deps/uv/test/test-getnameinfo.c
index b1391616d13e54..3767ffd9aea5de 100644
--- a/deps/uv/test/test-getnameinfo.c
+++ b/deps/uv/test/test-getnameinfo.c
@@ -66,6 +66,11 @@ TEST_IMPL(getnameinfo_basic_ip4) {
TEST_IMPL(getnameinfo_basic_ip4_sync) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
ASSERT(0 == uv_ip4_addr(address_ip4, port, &addr4));
ASSERT(0 == uv_getnameinfo(uv_default_loop(),
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index eb6665716f0718..24a8a657489a4e 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -346,6 +346,7 @@ TEST_DECLARE (fs_symlink_dir)
#ifdef _WIN32
TEST_DECLARE (fs_symlink_junction)
TEST_DECLARE (fs_non_symlink_reparse_point)
+TEST_DECLARE (fs_lstat_windows_store_apps)
TEST_DECLARE (fs_open_flags)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
@@ -409,6 +410,7 @@ TEST_DECLARE (fs_open_readonly_acl)
TEST_DECLARE (fs_fchmod_archive_readonly)
TEST_DECLARE (fs_invalid_mkdir_name)
#endif
+TEST_DECLARE (fs_get_system_error)
TEST_DECLARE (strscpy)
TEST_DECLARE (threadpool_queue_work_simple)
TEST_DECLARE (threadpool_queue_work_einval)
@@ -978,6 +980,7 @@ TASK_LIST_START
#ifdef _WIN32
TEST_ENTRY (fs_symlink_junction)
TEST_ENTRY (fs_non_symlink_reparse_point)
+ TEST_ENTRY (fs_lstat_windows_store_apps)
TEST_ENTRY (fs_open_flags)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
@@ -1036,6 +1039,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fchmod_archive_readonly)
TEST_ENTRY (fs_invalid_mkdir_name)
#endif
+ TEST_ENTRY (fs_get_system_error)
TEST_ENTRY (get_osfhandle_valid_handle)
TEST_ENTRY (open_osfhandle_valid_handle)
TEST_ENTRY (strscpy)
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index 65cfa1b3dcd4c4..f547ddfd7696ff 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -25,6 +25,11 @@
TEST_IMPL(platform_output) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
char buffer[512];
size_t rss;
size_t size;
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index b3308446f1d81f..edd75d38266768 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -592,10 +592,19 @@ static void start_poll_test(void) {
MAKE_VALGRIND_HAPPY();
}
-
+
+/* Issuing a shutdown() on IBM i PASE with parameter SHUT_WR
+ * also sends a normal close sequence to the partner program.
+ * This leads to timing issues and ECONNRESET failures in the
+ * test 'poll_duplex' and 'poll_unidirectional'.
+ *
+ * https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/apis/shutdn.htm
+ */
TEST_IMPL(poll_duplex) {
#if defined(NO_SELF_CONNECT)
RETURN_SKIP(NO_SELF_CONNECT);
+#elif defined(__PASE__)
+ RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE");
#endif
test_mode = DUPLEX;
start_poll_test();
@@ -606,6 +615,8 @@ TEST_IMPL(poll_duplex) {
TEST_IMPL(poll_unidirectional) {
#if defined(NO_SELF_CONNECT)
RETURN_SKIP(NO_SELF_CONNECT);
+#elif defined(__PASE__)
+ RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE");
#endif
test_mode = UNIDIRECTIONAL;
start_poll_test();
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 314a3562b02034..5e1c6d613003c0 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -1452,7 +1452,7 @@ TEST_IMPL(spawn_setuid_fails) {
options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
r = uv_spawn(uv_default_loop(), &process, &options);
-#if defined(__CYGWIN__) || defined(__PASE__)
+#if defined(__CYGWIN__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EPERM);
@@ -1497,7 +1497,7 @@ TEST_IMPL(spawn_setgid_fails) {
#endif
r = uv_spawn(uv_default_loop(), &process, &options);
-#if defined(__CYGWIN__) || defined(__MVS__) || defined(__PASE__)
+#if defined(__CYGWIN__) || defined(__MVS__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EPERM);
@@ -1689,7 +1689,7 @@ TEST_IMPL(spawn_reads_child_path) {
*/
#if defined(__APPLE__)
static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
-#elif defined __MVS__
+#elif defined(__MVS__) || defined(__PASE__)
static const char dyld_path_var[] = "LIBPATH";
#else
static const char dyld_path_var[] = "LD_LIBRARY_PATH";
diff --git a/deps/uv/test/test-tcp-write-after-connect.c b/deps/uv/test/test-tcp-write-after-connect.c
index 8198e7e184d5e4..8a698f44bd5db5 100644
--- a/deps/uv/test/test-tcp-write-after-connect.c
+++ b/deps/uv/test/test-tcp-write-after-connect.c
@@ -43,6 +43,11 @@ static void connect_cb(uv_connect_t *req, int status) {
TEST_IMPL(tcp_write_after_connect) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
struct sockaddr_in sa;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
ASSERT(0 == uv_loop_init(&loop));
diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c
index ffb392ceebc764..f53bce0601cea9 100644
--- a/deps/uv/test/test-thread.c
+++ b/deps/uv/test/test-thread.c
@@ -78,6 +78,10 @@ static void getaddrinfo_do(struct getaddrinfo_req* req) {
static void getaddrinfo_cb(uv_getaddrinfo_t* handle,
int status,
struct addrinfo* res) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
struct getaddrinfo_req* req;
ASSERT(status == 0);
diff --git a/deps/uv/test/test-udp-multicast-interface.c b/deps/uv/test/test-udp-multicast-interface.c
index 0b3c0e62da559f..9d36098d0d0ac2 100644
--- a/deps/uv/test/test-udp-multicast-interface.c
+++ b/deps/uv/test/test-udp-multicast-interface.c
@@ -54,6 +54,11 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
TEST_IMPL(udp_multicast_interface) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
int r;
uv_udp_send_t req;
uv_buf_t buf;
diff --git a/deps/uv/test/test-udp-multicast-interface6.c b/deps/uv/test/test-udp-multicast-interface6.c
index 40b05536dc7430..23a68a00f85625 100644
--- a/deps/uv/test/test-udp-multicast-interface6.c
+++ b/deps/uv/test/test-udp-multicast-interface6.c
@@ -54,6 +54,11 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
TEST_IMPL(udp_multicast_interface6) {
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
+
int r;
uv_udp_send_t req;
uv_buf_t buf;
diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c
index 5de27a7fb292db..40aa577d0a1b12 100644
--- a/deps/uv/test/test-udp-multicast-join6.c
+++ b/deps/uv/test/test-udp-multicast-join6.c
@@ -193,6 +193,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-udp-options.c b/deps/uv/test/test-udp-options.c
index d8c9d68d81b428..3ea51baf40b736 100644
--- a/deps/uv/test/test-udp-options.c
+++ b/deps/uv/test/test-udp-options.c
@@ -128,12 +128,16 @@ TEST_IMPL(udp_no_autobind) {
ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1));
#endif
ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1));
+/* TODO(gengjiawen): Fix test on QEMU. */
+#if defined(__QEMU__)
+ RETURN_SKIP("Test does not currently work in QEMU");
+#endif
ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0"));
uv_close((uv_handle_t*) &h, NULL);
/* Test a non-lazily initialized socket. */
- ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET));
+ ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET | UV_UDP_RECVMMSG));
ASSERT(0 == uv_udp_set_multicast_ttl(&h2, 32));
ASSERT(0 == uv_udp_set_broadcast(&h2, 1));
diff --git a/deps/uv/uv_win_longpath.manifest b/deps/uv/uv_win_longpath.manifest
new file mode 100644
index 00000000000000..8976e6dfca7657
--- /dev/null
+++ b/deps/uv/uv_win_longpath.manifest
@@ -0,0 +1,8 @@
+
+
+
+
+ true
+
+
+
diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h
index f2d2d1a9fd8945..0090313c8af2eb 100644
--- a/deps/uvwasi/include/uvwasi.h
+++ b/deps/uvwasi/include/uvwasi.h
@@ -5,13 +5,12 @@
extern "C" {
#endif
-#include "uv.h"
+#include "wasi_serdes.h"
#include "wasi_types.h"
-#include "fd_table.h"
#define UVWASI_VERSION_MAJOR 0
#define UVWASI_VERSION_MINOR 0
-#define UVWASI_VERSION_PATCH 8
+#define UVWASI_VERSION_PATCH 9
#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
(UVWASI_VERSION_MINOR << 8) | \
(UVWASI_VERSION_PATCH))
@@ -35,16 +34,18 @@ typedef struct uvwasi_mem_s {
uvwasi_realloc realloc;
} uvwasi_mem_t;
+struct uvwasi_fd_table_t;
+
typedef struct uvwasi_s {
- struct uvwasi_fd_table_t fds;
- size_t argc;
+ struct uvwasi_fd_table_t* fds;
+ uvwasi_size_t argc;
char** argv;
char* argv_buf;
- size_t argv_buf_size;
- size_t envc;
+ uvwasi_size_t argv_buf_size;
+ uvwasi_size_t envc;
char** env;
char* env_buf;
- size_t env_buf_size;
+ uvwasi_size_t env_buf_size;
const uvwasi_mem_t* allocator;
} uvwasi_t;
@@ -54,12 +55,12 @@ typedef struct uvwasi_preopen_s {
} uvwasi_preopen_t;
typedef struct uvwasi_options_s {
- size_t fd_table_size;
- size_t preopenc;
+ uvwasi_size_t fd_table_size;
+ uvwasi_size_t preopenc;
uvwasi_preopen_t* preopens;
- size_t argc;
- char** argv;
- char** envp;
+ uvwasi_size_t argc;
+ const char** argv;
+ const char** envp;
uvwasi_fd_t in;
uvwasi_fd_t out;
uvwasi_fd_t err;
@@ -69,17 +70,18 @@ typedef struct uvwasi_options_s {
/* Embedder API. */
uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
void uvwasi_destroy(uvwasi_t* uvwasi);
+/* Use int instead of uv_file to avoid needing uv.h */
uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
const uvwasi_fd_t fd,
- uv_file new_host_fd);
+ int new_host_fd);
const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code);
/* WASI system call API. */
uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf);
uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
- size_t* argc,
- size_t* argv_buf_size);
+ uvwasi_size_t* argc,
+ uvwasi_size_t* argv_buf_size);
uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t* resolution);
@@ -91,8 +93,8 @@ uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
char** environment,
char* environ_buf);
uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
- size_t* environ_count,
- size_t* environ_buf_size);
+ uvwasi_size_t* environ_count,
+ uvwasi_size_t* environ_buf_size);
uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_filesize_t offset,
@@ -129,33 +131,33 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
- size_t iovs_len,
+ uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
- size_t* nread);
+ uvwasi_size_t* nread);
uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_prestat_t* buf);
uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
char* path,
- size_t path_len);
+ uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
- size_t iovs_len,
+ uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
- size_t* nwritten);
+ uvwasi_size_t* nwritten);
uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
- size_t iovs_len,
- size_t* nread);
+ uvwasi_size_t iovs_len,
+ uvwasi_size_t* nread);
uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
void* buf,
- size_t buf_len,
+ uvwasi_size_t buf_len,
uvwasi_dircookie_t cookie,
- size_t* bufused);
+ uvwasi_size_t* bufused);
uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
uvwasi_fd_t from,
uvwasi_fd_t to);
@@ -171,23 +173,23 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
- size_t iovs_len,
- size_t* nwritten);
+ uvwasi_size_t iovs_len,
+ uvwasi_size_t* nwritten);
uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len);
+ uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_filestat_t* buf);
uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
@@ -195,15 +197,15 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
uvwasi_lookupflags_t old_flags,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
- size_t new_path_len);
+ uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_fd_t dirfd,
uvwasi_lookupflags_t dirflags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_oflags_t o_flags,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting,
@@ -212,53 +214,55 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char* buf,
- size_t buf_len,
- size_t* bufused);
+ uvwasi_size_t buf_len,
+ uvwasi_size_t* bufused);
uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len);
+ uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
- size_t new_path_len);
+ uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t fd,
const char* new_path,
- size_t new_path_len);
+ uvwasi_size_t new_path_len);
uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len);
+ uvwasi_size_t path_len);
uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
const uvwasi_subscription_t* in,
uvwasi_event_t* out,
- size_t nsubscriptions,
- size_t* nevents);
+ uvwasi_size_t nsubscriptions,
+ uvwasi_size_t* nevents);
uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval);
uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig);
-uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len);
+uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
+ void* buf,
+ uvwasi_size_t buf_len);
uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi);
uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_iovec_t* ri_data,
- size_t ri_data_len,
+ uvwasi_size_t ri_data_len,
uvwasi_riflags_t ri_flags,
- size_t* ro_datalen,
+ uvwasi_size_t* ro_datalen,
uvwasi_roflags_t* ro_flags);
uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_ciovec_t* si_data,
- size_t si_data_len,
+ uvwasi_size_t si_data_len,
uvwasi_siflags_t si_flags,
- size_t* so_datalen);
+ uvwasi_size_t* so_datalen);
uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
uvwasi_sdflags_t how);
diff --git a/deps/uvwasi/include/wasi_serdes.h b/deps/uvwasi/include/wasi_serdes.h
new file mode 100644
index 00000000000000..f927b82bac9cbc
--- /dev/null
+++ b/deps/uvwasi/include/wasi_serdes.h
@@ -0,0 +1,145 @@
+#ifndef __UVWASI_SERDES_H__
+#define __UVWASI_SERDES_H__
+
+#include "wasi_types.h"
+
+/* Basic uint{8,16,32,64}_t read/write functions. */
+
+#define BASIC_TYPE_(name, type) \
+ void uvwasi_serdes_write_##name(void* ptr, size_t offset, type value); \
+ type uvwasi_serdes_read_##name(const void* ptr, size_t offset); \
+
+#define BASIC_TYPE(type) BASIC_TYPE_(type, type)
+#define BASIC_TYPE_UVWASI(type) BASIC_TYPE_(type, uvwasi_##type)
+
+#define UVWASI_SERDES_SIZE_uint8_t sizeof(uint8_t)
+BASIC_TYPE(uint8_t)
+#define UVWASI_SERDES_SIZE_uint16_t sizeof(uint16_t)
+BASIC_TYPE(uint16_t)
+#define UVWASI_SERDES_SIZE_uint32_t sizeof(uint32_t)
+BASIC_TYPE(uint32_t)
+#define UVWASI_SERDES_SIZE_uint64_t sizeof(uint64_t)
+BASIC_TYPE(uint64_t)
+
+#define UVWASI_SERDES_SIZE_advice_t sizeof(uvwasi_advice_t)
+BASIC_TYPE_UVWASI(advice_t)
+#define UVWASI_SERDES_SIZE_clockid_t sizeof(uvwasi_clockid_t)
+BASIC_TYPE_UVWASI(clockid_t)
+#define UVWASI_SERDES_SIZE_device_t sizeof(uvwasi_device_t)
+BASIC_TYPE_UVWASI(device_t)
+#define UVWASI_SERDES_SIZE_dircookie_t sizeof(uvwasi_dircookie_t)
+BASIC_TYPE_UVWASI(dircookie_t)
+#define UVWASI_SERDES_SIZE_eventrwflags_t sizeof(uvwasi_eventrwflags_t)
+BASIC_TYPE_UVWASI(eventrwflags_t)
+#define UVWASI_SERDES_SIZE_eventtype_t sizeof(uvwasi_eventtype_t)
+BASIC_TYPE_UVWASI(eventtype_t)
+#define UVWASI_SERDES_SIZE_exitcode_t sizeof(uvwasi_exitcode_t)
+BASIC_TYPE_UVWASI(exitcode_t)
+#define UVWASI_SERDES_SIZE_fd_t sizeof(uvwasi_fd_t)
+BASIC_TYPE_UVWASI(fd_t)
+#define UVWASI_SERDES_SIZE_fdflags_t sizeof(uvwasi_fdflags_t)
+BASIC_TYPE_UVWASI(fdflags_t)
+#define UVWASI_SERDES_SIZE_filesize_t sizeof(uvwasi_filesize_t)
+BASIC_TYPE_UVWASI(filesize_t)
+#define UVWASI_SERDES_SIZE_fstflags_t sizeof(uvwasi_fstflags_t)
+BASIC_TYPE_UVWASI(fstflags_t)
+#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
+BASIC_TYPE_UVWASI(inode_t)
+#define UVWASI_SERDES_SIZE_linkcount_t sizeof(uvwasi_linkcount_t)
+BASIC_TYPE_UVWASI(linkcount_t)
+#define UVWASI_SERDES_SIZE_lookupflags_t sizeof(uvwasi_lookupflags_t)
+BASIC_TYPE_UVWASI(lookupflags_t)
+#define UVWASI_SERDES_SIZE_oflags_t sizeof(uvwasi_oflags_t)
+BASIC_TYPE_UVWASI(oflags_t)
+#define UVWASI_SERDES_SIZE_preopentype_t sizeof(uvwasi_preopentype_t)
+BASIC_TYPE_UVWASI(preopentype_t)
+#define UVWASI_SERDES_SIZE_riflags_t sizeof(uvwasi_riflags_t)
+BASIC_TYPE_UVWASI(riflags_t)
+#define UVWASI_SERDES_SIZE_rights_t sizeof(uvwasi_rights_t)
+BASIC_TYPE_UVWASI(rights_t)
+#define UVWASI_SERDES_SIZE_roflags_t sizeof(uvwasi_roflags_t)
+BASIC_TYPE_UVWASI(roflags_t)
+#define UVWASI_SERDES_SIZE_sdflags_t sizeof(uvwasi_sdflags_t)
+BASIC_TYPE_UVWASI(sdflags_t)
+#define UVWASI_SERDES_SIZE_siflags_t sizeof(uvwasi_siflags_t)
+BASIC_TYPE_UVWASI(siflags_t)
+#define UVWASI_SERDES_SIZE_size_t sizeof(uvwasi_size_t)
+BASIC_TYPE_UVWASI(size_t)
+#define UVWASI_SERDES_SIZE_inode_t sizeof(uvwasi_inode_t)
+BASIC_TYPE_UVWASI(inode_t)
+#define UVWASI_SERDES_SIZE_signal_t sizeof(uvwasi_signal_t)
+BASIC_TYPE_UVWASI(signal_t)
+#define UVWASI_SERDES_SIZE_subclockflags_t sizeof(uvwasi_subclockflags_t)
+BASIC_TYPE_UVWASI(subclockflags_t)
+#define UVWASI_SERDES_SIZE_timestamp_t sizeof(uvwasi_timestamp_t)
+BASIC_TYPE_UVWASI(timestamp_t)
+#define UVWASI_SERDES_SIZE_userdata_t sizeof(uvwasi_userdata_t)
+BASIC_TYPE_UVWASI(userdata_t)
+#define UVWASI_SERDES_SIZE_whence_t sizeof(uvwasi_whence_t)
+BASIC_TYPE_UVWASI(whence_t)
+
+#undef BASIC_TYPE_UVWASI
+#undef BASIC_TYPE
+#undef BASIC_TYPE_
+
+/* WASI structure read/write functions. */
+
+#define STRUCT(name) \
+ void uvwasi_serdes_write_##name(void* ptr, \
+ size_t offset, \
+ const uvwasi_##name* value); \
+ void uvwasi_serdes_read_##name(const void* ptr, \
+ size_t offset, \
+ uvwasi_##name* value);
+
+/* iovs currently only need to be read from WASM memory. */
+#define IOVS_STRUCT(name) \
+ uvwasi_errno_t uvwasi_serdes_read_##name(const void* ptr, \
+ size_t end, \
+ size_t offset, \
+ uvwasi_##name* value);
+
+#define UVWASI_SERDES_SIZE_ciovec_t 8
+IOVS_STRUCT(ciovec_t)
+
+#define UVWASI_SERDES_SIZE_iovec_t 8
+IOVS_STRUCT(iovec_t)
+
+#define UVWASI_SERDES_SIZE_fdstat_t 24
+STRUCT(fdstat_t)
+
+#define UVWASI_SERDES_SIZE_filestat_t 64
+STRUCT(filestat_t)
+
+#define UVWASI_SERDES_SIZE_prestat_t 8
+STRUCT(prestat_t)
+
+#define UVWASI_SERDES_SIZE_event_t 32
+STRUCT(event_t)
+
+#define UVWASI_SERDES_SIZE_subscription_t 48
+STRUCT(subscription_t)
+
+#undef STRUCT
+#undef IOVS_STRUCT
+
+uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_ciovec_t* iovs,
+ uvwasi_size_t iovs_len);
+
+uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_iovec_t* iovs,
+ uvwasi_size_t iovs_len);
+
+/* Helper functions for memory bounds checking. */
+int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size);
+int uvwasi_serdes_check_array_bounds(size_t offset,
+ size_t end,
+ size_t size,
+ size_t count);
+
+#endif /* __UVWASI_SERDES_H__ */
diff --git a/deps/uvwasi/include/wasi_types.h b/deps/uvwasi/include/wasi_types.h
index 2f93b412624c06..57c2dd2f3ce589 100644
--- a/deps/uvwasi/include/wasi_types.h
+++ b/deps/uvwasi/include/wasi_types.h
@@ -6,6 +6,8 @@
/* API: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md */
+typedef uint32_t uvwasi_size_t;
+
typedef uint8_t uvwasi_advice_t;
#define UVWASI_ADVICE_NORMAL 0
#define UVWASI_ADVICE_SEQUENTIAL 1
@@ -16,7 +18,7 @@ typedef uint8_t uvwasi_advice_t;
typedef struct uvwasi_ciovec_s {
const void* buf;
- size_t buf_len;
+ uvwasi_size_t buf_len;
} uvwasi_ciovec_t;
typedef uint32_t uvwasi_clockid_t;
@@ -152,7 +154,7 @@ typedef uint64_t uvwasi_inode_t;
typedef struct uvwasi_iovec_s {
void* buf;
- size_t buf_len;
+ uvwasi_size_t buf_len;
} uvwasi_iovec_t;
typedef uint64_t uvwasi_linkcount_t;
@@ -173,7 +175,7 @@ typedef struct uvwasi_prestat_s {
uvwasi_preopentype_t pr_type;
union uvwasi_prestat_u {
struct uvwasi_prestat_dir_t {
- size_t pr_name_len;
+ uvwasi_size_t pr_name_len;
} dir;
} u;
} uvwasi_prestat_t;
diff --git a/deps/uvwasi/src/debug.h b/deps/uvwasi/src/debug.h
new file mode 100644
index 00000000000000..16bc2732ec90cd
--- /dev/null
+++ b/deps/uvwasi/src/debug.h
@@ -0,0 +1,13 @@
+#ifndef __UVWASI_DEBUG_H__
+#define __UVWASI_DEBUG_H__
+
+#ifdef UVWASI_DEBUG_LOG
+# define __STDC_FORMAT_MACROS
+# include
+# define DEBUG(fmt, ...) \
+ do { fprintf(stderr, fmt, __VA_ARGS__); } while (0)
+#else
+# define DEBUG(fmt, ...)
+#endif
+
+#endif /* __UVWASI_DEBUG_H__ */
diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c
index 3d134e3b7e5e2e..877faf4ca19cd0 100644
--- a/deps/uvwasi/src/fd_table.c
+++ b/deps/uvwasi/src/fd_table.c
@@ -181,26 +181,25 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
if (uvwasi == NULL || options == NULL || options->fd_table_size < 3)
return UVWASI_EINVAL;
- table = &uvwasi->fds;
- table->fds = NULL;
+ table = uvwasi__malloc(uvwasi, sizeof(*table));
+ if (table == NULL)
+ return UVWASI_ENOMEM;
+
table->used = 0;
table->size = options->fd_table_size;
table->fds = uvwasi__calloc(uvwasi,
options->fd_table_size,
sizeof(struct uvwasi_fd_wrap_t*));
-
- if (table->fds == NULL)
+ if (table->fds == NULL) {
+ uvwasi__free(uvwasi, table);
return UVWASI_ENOMEM;
+ }
r = uv_rwlock_init(&table->rwlock);
if (r != 0) {
err = uvwasi__translate_uv_error(r);
- /* Free table->fds and set it to NULL here. This is done explicitly instead
- of jumping to error_exit because uvwasi_fd_table_free() relies on fds
- being NULL to know whether or not to destroy the rwlock.
- */
uvwasi__free(uvwasi, table->fds);
- table->fds = NULL;
+ uvwasi__free(uvwasi, table);
return err;
}
@@ -217,6 +216,7 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
goto error_exit;
+ uvwasi->fds = table;
return UVWASI_ESUCCESS;
error_exit:
uvwasi_fd_table_free(uvwasi, table);
@@ -228,12 +228,14 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
struct uvwasi_fd_wrap_t* entry;
uint32_t i;
- if (table == NULL)
+ if (uvwasi == NULL || table == NULL)
return;
for (i = 0; i < table->size; i++) {
entry = table->fds[i];
- if (entry == NULL) continue;
+
+ if (entry == NULL)
+ continue;
uv_mutex_destroy(&entry->mutex);
uvwasi__free(uvwasi, entry);
@@ -246,6 +248,8 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
table->used = 0;
uv_rwlock_destroy(&table->rwlock);
}
+
+ uvwasi__free(uvwasi, table);
}
diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/src/fd_table.h
similarity index 100%
rename from deps/uvwasi/include/fd_table.h
rename to deps/uvwasi/src/fd_table.h
diff --git a/deps/uvwasi/src/path_resolver.c b/deps/uvwasi/src/path_resolver.c
index ee0e60f7e8f4ea..af13c1553ca874 100644
--- a/deps/uvwasi/src/path_resolver.c
+++ b/deps/uvwasi/src/path_resolver.c
@@ -15,7 +15,7 @@
#endif /* _WIN32 */
-static int uvwasi__is_absolute_path(const char* path, size_t path_len) {
+static int uvwasi__is_absolute_path(const char* path, uvwasi_size_t path_len) {
/* It's expected that only Unix style paths will be generated by WASI. */
return path != NULL && path_len > 0 && path[0] == '/';
}
@@ -33,9 +33,9 @@ static char* uvwasi__strchr_slash(const char* s) {
uvwasi_errno_t uvwasi__normalize_path(const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char* normalized_path,
- size_t normalized_len) {
+ uvwasi_size_t normalized_len) {
const char* cur;
char* ptr;
char* next;
@@ -125,9 +125,9 @@ uvwasi_errno_t uvwasi__normalize_path(const char* path,
static int uvwasi__is_path_sandboxed(const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
const char* fd_path,
- size_t fd_path_len) {
+ uvwasi_size_t fd_path_len) {
char* ptr;
int remaining_len;
@@ -173,9 +173,9 @@ static uvwasi_errno_t uvwasi__normalize_absolute_path(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char** normalized_path,
- size_t* normalized_len
+ uvwasi_size_t* normalized_len
) {
/* This function resolves an absolute path to the provided file descriptor.
If the file descriptor's path is relative, then this operation will fail
@@ -224,9 +224,9 @@ static uvwasi_errno_t uvwasi__normalize_relative_path(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char** normalized_path,
- size_t* normalized_len
+ uvwasi_size_t* normalized_len
) {
/* This function resolves a relative path to the provided file descriptor.
The relative path is concatenated to the file descriptor's path, and then
@@ -298,9 +298,9 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char** resolved_path,
- size_t* resolved_len
+ uvwasi_size_t* resolved_len
) {
/* Return the normalized path, but resolved to the host's real path. */
char* res_path;
@@ -309,7 +309,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
int fake_path_len;
int stripped_len;
#ifdef _WIN32
- size_t i;
+ uvwasi_size_t i;
#endif /* _WIN32 */
real_path_len = strlen(fd->real_path);
@@ -351,6 +351,7 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
#ifdef _WIN32
/* Replace / with \ on Windows. */
+ res_path = *resolved_path;
for (i = real_path_len; i < *resolved_len; i++) {
if (res_path[i] == '/')
res_path[i] = '\\';
@@ -364,8 +365,8 @@ static uvwasi_errno_t uvwasi__resolve_path_to_host(
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
- size_t path_len,
- char* resolved_path,
+ uvwasi_size_t path_len,
+ char** resolved_path,
uvwasi_lookupflags_t flags) {
uv_fs_t req;
uvwasi_errno_t err;
@@ -373,9 +374,9 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
char* host_path;
char* normalized_path;
char* link_target;
- size_t input_len;
- size_t host_path_len;
- size_t normalized_len;
+ uvwasi_size_t input_len;
+ uvwasi_size_t host_path_len;
+ uvwasi_size_t normalized_len;
int follow_count;
int r;
@@ -418,14 +419,6 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
goto exit;
- /* TODO(cjihrig): Currently performing a bounds check here. The TODO is to
- stop allocating resolved_path in every caller and instead return the
- path allocated in this function. */
- if (host_path_len > PATH_MAX_BYTES) {
- err = UVWASI_ENOBUFS;
- goto exit;
- }
-
if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
r = uv_fs_readlink(NULL, &req, host_path, NULL);
@@ -482,11 +475,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
}
exit:
- if (err == UVWASI_ESUCCESS)
- memcpy(resolved_path, host_path, host_path_len + 1);
+ if (err == UVWASI_ESUCCESS) {
+ *resolved_path = host_path;
+ } else {
+ *resolved_path = NULL;
+ uvwasi__free(uvwasi, host_path);
+ }
uvwasi__free(uvwasi, link_target);
uvwasi__free(uvwasi, normalized_path);
- uvwasi__free(uvwasi, host_path);
return err;
}
diff --git a/deps/uvwasi/src/path_resolver.h b/deps/uvwasi/src/path_resolver.h
index d5f95eafbfbf83..5040c69ac40cb7 100644
--- a/deps/uvwasi/src/path_resolver.h
+++ b/deps/uvwasi/src/path_resolver.h
@@ -1,28 +1,19 @@
#ifndef __UVWASI_PATH_RESOLVER_H__
#define __UVWASI_PATH_RESOLVER_H__
+#include "fd_table.h"
#include "uvwasi.h"
-/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths
- can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */
-#ifdef _WIN32
-/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
-# define PATH_MAX_BYTES (MAX_PATH * 4)
-#else
-# include
-# define PATH_MAX_BYTES (PATH_MAX)
-#endif
-
uvwasi_errno_t uvwasi__normalize_path(const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char* normalized_path,
- size_t normalized_len);
+ uvwasi_size_t normalized_len);
uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
- size_t path_len,
- char* resolved_path,
+ uvwasi_size_t path_len,
+ char** resolved_path,
uvwasi_lookupflags_t flags);
#endif /* __UVWASI_PATH_RESOLVER_H__ */
diff --git a/deps/uvwasi/src/poll_oneoff.c b/deps/uvwasi/src/poll_oneoff.c
new file mode 100644
index 00000000000000..a4b1c3c84282fa
--- /dev/null
+++ b/deps/uvwasi/src/poll_oneoff.c
@@ -0,0 +1,269 @@
+#include "uv.h"
+#include "poll_oneoff.h"
+#include "uv_mapping.h"
+#include "uvwasi_alloc.h"
+
+
+static void poll_cb(uv_poll_t* handle, int status, int events) {
+ struct uvwasi_poll_oneoff_state_t* state;
+ struct uvwasi__poll_fdevent_t* event;
+
+ uv_poll_stop(handle);
+ event = uv_handle_get_data((uv_handle_t*) handle);
+ event->revents = events;
+
+ if (status != 0)
+ event->error = UVWASI_EIO;
+
+ state = uv_loop_get_data(handle->loop);
+ state->result++;
+}
+
+
+static void timeout_cb(uv_timer_t* handle) {
+ struct uvwasi_poll_oneoff_state_t* state;
+ uvwasi_size_t i;
+
+ state = uv_loop_get_data(handle->loop);
+
+ for (i = 0; i < state->handle_cnt; i++)
+ uv_poll_stop(&state->poll_handles[i]);
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_init(
+ uvwasi_t* uvwasi,
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_size_t max_fds
+ ) {
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || state == NULL)
+ return UVWASI_EINVAL;
+
+ state->uvwasi = NULL;
+ state->timeout = 0;
+ state->has_timer = 0;
+ state->fdevents = NULL;
+ state->poll_handles = NULL;
+ state->max_fds = 0;
+ state->fdevent_cnt = 0;
+ state->handle_cnt = 0;
+ state->result = 0;
+
+ r = uv_loop_init(&state->loop);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ if (max_fds > 0) {
+ state->fdevents = uvwasi__calloc(uvwasi,
+ max_fds,
+ sizeof(*state->fdevents));
+ if (state->fdevents == NULL) {
+ err = UVWASI_ENOMEM;
+ goto error_exit;
+ }
+
+ state->poll_handles = uvwasi__calloc(uvwasi,
+ max_fds,
+ sizeof(*state->poll_handles));
+ if (state->poll_handles == NULL) {
+ err = UVWASI_ENOMEM;
+ goto error_exit;
+ }
+ }
+
+ uv_loop_set_data(&state->loop, (void*) state);
+ state->uvwasi = uvwasi;
+ state->max_fds = max_fds;
+
+ return UVWASI_ESUCCESS;
+
+error_exit:
+ uv_loop_close(&state->loop);
+ uvwasi__free(state->uvwasi, state->fdevents);
+ uvwasi__free(state->uvwasi, state->poll_handles);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
+ struct uvwasi_poll_oneoff_state_t* state
+ ) {
+ struct uvwasi__poll_fdevent_t* event;
+ uvwasi_size_t i;
+ int r;
+
+ if (state == NULL)
+ return UVWASI_EINVAL;
+
+ if (state->has_timer != 0) {
+ state->timeout = 0;
+ state->has_timer = 0;
+ uv_close((uv_handle_t*) &state->timer, NULL);
+ }
+
+ for (i = 0; i < state->fdevent_cnt; i++) {
+ event = &state->fdevents[i];
+
+ if (event->is_duplicate_fd == 0 && event->wrap != NULL)
+ uv_mutex_unlock(&event->wrap->mutex);
+ }
+
+ for (i = 0; i < state->handle_cnt; i++)
+ uv_close((uv_handle_t*) &state->poll_handles[i], NULL);
+
+ uv_run(&state->loop, UV_RUN_NOWAIT);
+
+ state->max_fds = 0;
+ state->fdevent_cnt = 0;
+ state->handle_cnt = 0;
+
+ uvwasi__free(state->uvwasi, state->fdevents);
+ uvwasi__free(state->uvwasi, state->poll_handles);
+ state->fdevents = NULL;
+ state->poll_handles = NULL;
+ state->uvwasi = NULL;
+
+ r = uv_loop_close(&state->loop);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_timestamp_t timeout
+ ) {
+ int r;
+
+ if (state == NULL)
+ return UVWASI_EINVAL;
+
+ r = uv_timer_init(&state->loop, &state->timer);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ /* Convert WASI timeout from nanoseconds to milliseconds for libuv. */
+ state->timeout = timeout / 1000000;
+ state->has_timer = 1;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_subscription_t* subscription
+ ) {
+ struct uvwasi__poll_fdevent_t* event;
+ struct uvwasi__poll_fdevent_t* dup;
+ uv_poll_t* poll_handle;
+ uvwasi_eventtype_t type;
+ uvwasi_rights_t rights;
+ uvwasi_fd_t fd;
+ uvwasi_errno_t err;
+ uvwasi_size_t i;
+ int r;
+
+ if (state == NULL)
+ return UVWASI_EINVAL;
+
+ event = &state->fdevents[state->fdevent_cnt];
+ fd = subscription->u.fd_readwrite.fd;
+ type = subscription->type;
+
+ if (type == UVWASI_EVENTTYPE_FD_READ) {
+ event->events = UV_DISCONNECT | UV_READABLE;
+ rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_READ;
+ } else if (type == UVWASI_EVENTTYPE_FD_WRITE) {
+ event->events = UV_DISCONNECT | UV_WRITABLE;
+ rights = UVWASI_RIGHT_POLL_FD_READWRITE | UVWASI_RIGHT_FD_WRITE;
+ } else {
+ return UVWASI_EINVAL;
+ }
+
+ /* Check if the same file descriptor is already being polled. If so, use the
+ wrap and poll handle from the first descriptor. The reasons are that libuv
+ does not support polling the same fd more than once at the same time, and
+ uvwasi has the fd's mutex locked. */
+ event->is_duplicate_fd = 0;
+ for (i = 0; i < state->fdevent_cnt; i++) {
+ dup = &state->fdevents[i];
+ if (dup->wrap->id == fd) {
+ event->is_duplicate_fd = 1;
+ event->wrap = dup->wrap;
+ event->poll_handle = dup->poll_handle;
+ err = event->error;
+ goto poll_config_done;
+ }
+ }
+
+ /* Get the file descriptor. If UVWASI_EBADF is returned, continue on, but
+ don't do any polling with the handle. */
+ err = uvwasi_fd_table_get(state->uvwasi->fds, fd, &event->wrap, rights, 0);
+ if (err == UVWASI_EBADF)
+ event->wrap = NULL;
+ else if (err != UVWASI_ESUCCESS)
+ return err;
+
+ if (err == UVWASI_ESUCCESS) {
+ /* The fd is valid, so setup the poll handle. */
+ poll_handle = &state->poll_handles[state->handle_cnt];
+ r = uv_poll_init(&state->loop, poll_handle, event->wrap->fd);
+
+ if (r != 0) {
+ /* If uv_poll_init() fails (for example on Windows because only sockets
+ are supported), set the error for this event to UVWASI_EBADF, but don't
+ do any polling with the handle. */
+ uv_mutex_unlock(&event->wrap->mutex);
+ return uvwasi__translate_uv_error(r);
+ } else {
+ r = uv_poll_start(poll_handle,
+ event->events,
+ poll_cb);
+ if (r != 0) {
+ uv_mutex_unlock(&event->wrap->mutex);
+ uv_close((uv_handle_t*) poll_handle, NULL);
+ return uvwasi__translate_uv_error(r);
+ }
+
+ uv_handle_set_data((uv_handle_t*) poll_handle,
+ (void*) &state->fdevents[state->fdevent_cnt]);
+ event->poll_handle = poll_handle;
+ state->handle_cnt++;
+ }
+ }
+
+poll_config_done:
+ event->type = type;
+ event->userdata = subscription->userdata;
+ event->error = err;
+ event->revents = 0;
+ state->fdevent_cnt++;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_run(
+ struct uvwasi_poll_oneoff_state_t* state
+ ) {
+ int r;
+
+ if (state->has_timer == 1) {
+ r = uv_timer_start(&state->timer, timeout_cb, state->timeout, 0);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ if (state->fdevent_cnt > 0)
+ uv_unref((uv_handle_t*) &state->timer);
+ }
+
+ r = uv_run(&state->loop, UV_RUN_DEFAULT);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
diff --git a/deps/uvwasi/src/poll_oneoff.h b/deps/uvwasi/src/poll_oneoff.h
new file mode 100644
index 00000000000000..64a315af1b334b
--- /dev/null
+++ b/deps/uvwasi/src/poll_oneoff.h
@@ -0,0 +1,60 @@
+#ifndef __UVWASI_POLL_ONEOFF_H__
+#define __UVWASI_POLL_ONEOFF_H__
+
+#include "fd_table.h"
+#include "wasi_types.h"
+
+struct uvwasi_s;
+
+struct uvwasi__poll_fdevent_t {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_userdata_t userdata;
+ uvwasi_eventtype_t type;
+ uvwasi_errno_t error;
+ uv_poll_t* poll_handle;
+ int is_duplicate_fd;
+ int events;
+ int revents;
+};
+
+struct uvwasi_poll_oneoff_state_t {
+ struct uvwasi_s* uvwasi;
+ struct uvwasi__poll_fdevent_t* fdevents;
+ uv_poll_t* poll_handles;
+ uv_timer_t timer;
+ uint64_t timeout;
+ uv_loop_t loop;
+ uvwasi_size_t max_fds;
+ int has_timer;
+ uvwasi_size_t fdevent_cnt;
+ uvwasi_size_t handle_cnt;
+ int result;
+};
+
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_init(
+ struct uvwasi_s* uvwasi,
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_size_t max_fds
+ );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_cleanup(
+ struct uvwasi_poll_oneoff_state_t* state
+ );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_set_timer(
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_timestamp_t timeout
+ );
+
+uvwasi_errno_t uvwasi__poll_oneoff_state_add_fdevent(
+ struct uvwasi_poll_oneoff_state_t* state,
+ uvwasi_subscription_t* subscription
+ );
+
+uvwasi_errno_t uvwasi__poll_oneoff_run(
+ struct uvwasi_poll_oneoff_state_t* state
+ );
+
+
+#endif /* __UVWASI_POLL_ONEOFF_H__ */
diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c
index 0ee66be36a3951..fc8f0ee4844b9e 100644
--- a/deps/uvwasi/src/uvwasi.c
+++ b/deps/uvwasi/src/uvwasi.c
@@ -20,7 +20,9 @@
#include "fd_table.h"
#include "clocks.h"
#include "path_resolver.h"
+#include "poll_oneoff.h"
#include "wasi_rights.h"
+#include "debug.h"
/* IBMi PASE does not support posix_fadvise() */
#ifdef __PASE__
@@ -109,9 +111,9 @@ static uvwasi_errno_t uvwasi__lseek(uv_file fd,
static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
uv_buf_t** buffers,
const uvwasi_iovec_t* iovs,
- size_t iovs_len) {
+ uvwasi_size_t iovs_len) {
uv_buf_t* bufs;
- size_t i;
+ uvwasi_size_t i;
if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
return UVWASI_ENOMEM;
@@ -131,9 +133,9 @@ static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
static uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi,
uv_buf_t** buffers,
const uvwasi_ciovec_t* iovs,
- size_t iovs_len) {
+ uvwasi_size_t iovs_len) {
uv_buf_t* bufs;
- size_t i;
+ uvwasi_size_t i;
if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
return UVWASI_ENOMEM;
@@ -154,12 +156,12 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
uv_fs_t realpath_req;
uv_fs_t open_req;
uvwasi_errno_t err;
- size_t args_size;
- size_t size;
- size_t offset;
- size_t env_count;
- size_t env_buf_size;
- size_t i;
+ uvwasi_size_t args_size;
+ uvwasi_size_t size;
+ uvwasi_size_t offset;
+ uvwasi_size_t env_count;
+ uvwasi_size_t env_buf_size;
+ uvwasi_size_t i;
int r;
if (uvwasi == NULL || options == NULL || options->fd_table_size == 0)
@@ -173,7 +175,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
uvwasi->argv = NULL;
uvwasi->env_buf = NULL;
uvwasi->env = NULL;
- uvwasi->fds.fds = NULL;
+ uvwasi->fds = NULL;
args_size = 0;
for (i = 0; i < options->argc; ++i)
@@ -270,7 +272,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
}
err = uvwasi_fd_table_insert_preopen(uvwasi,
- &uvwasi->fds,
+ uvwasi->fds,
open_req.result,
options->preopens[i].mapped_path,
realpath_req.ptr);
@@ -293,11 +295,12 @@ void uvwasi_destroy(uvwasi_t* uvwasi) {
if (uvwasi == NULL)
return;
- uvwasi_fd_table_free(uvwasi, &uvwasi->fds);
+ uvwasi_fd_table_free(uvwasi, uvwasi->fds);
uvwasi__free(uvwasi, uvwasi->argv_buf);
uvwasi__free(uvwasi, uvwasi->argv);
uvwasi__free(uvwasi, uvwasi->env_buf);
uvwasi__free(uvwasi, uvwasi->env);
+ uvwasi->fds = NULL;
uvwasi->argv_buf = NULL;
uvwasi->argv = NULL;
uvwasi->env_buf = NULL;
@@ -314,7 +317,7 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -325,7 +328,12 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) {
- size_t i;
+ uvwasi_size_t i;
+
+ DEBUG("uvwasi_args_get(uvwasi=%p, argv=%p, argv_buf=%p)\n",
+ uvwasi,
+ argv,
+ argv_buf);
if (uvwasi == NULL || argv == NULL || argv_buf == NULL)
return UVWASI_EINVAL;
@@ -340,8 +348,13 @@ uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) {
uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
- size_t* argc,
- size_t* argv_buf_size) {
+ uvwasi_size_t* argc,
+ uvwasi_size_t* argv_buf_size) {
+ DEBUG("uvwasi_args_sizes_get(uvwasi=%p, argc=%p, argv_buf_size=%p)\n",
+ uvwasi,
+ argc,
+ argv_buf_size);
+
if (uvwasi == NULL || argc == NULL || argv_buf_size == NULL)
return UVWASI_EINVAL;
@@ -354,6 +367,11 @@ uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t* resolution) {
+ DEBUG("uvwasi_clock_res_get(uvwasi=%p, clock_id=%d, resolution=%p)\n",
+ uvwasi,
+ clock_id,
+ resolution);
+
if (uvwasi == NULL || resolution == NULL)
return UVWASI_EINVAL;
@@ -376,6 +394,13 @@ uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
uvwasi_clockid_t clock_id,
uvwasi_timestamp_t precision,
uvwasi_timestamp_t* time) {
+ DEBUG("uvwasi_clock_time_get(uvwasi=%p, clock_id=%d, "
+ "precision=%"PRIu64", time=%p)\n",
+ uvwasi,
+ clock_id,
+ precision,
+ time);
+
if (uvwasi == NULL || time == NULL)
return UVWASI_EINVAL;
@@ -398,7 +423,12 @@ uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
char** environment,
char* environ_buf) {
- size_t i;
+ uvwasi_size_t i;
+
+ DEBUG("uvwasi_environ_get(uvwasi=%p, environment=%p, environ_buf=%p)\n",
+ uvwasi,
+ environment,
+ environ_buf);
if (uvwasi == NULL || environment == NULL || environ_buf == NULL)
return UVWASI_EINVAL;
@@ -413,8 +443,14 @@ uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
- size_t* environ_count,
- size_t* environ_buf_size) {
+ uvwasi_size_t* environ_count,
+ uvwasi_size_t* environ_buf_size) {
+ DEBUG("uvwasi_environ_sizes_get(uvwasi=%p, environ_count=%p, "
+ "environ_buf_size=%p)\n",
+ uvwasi,
+ environ_count,
+ environ_buf_size);
+
if (uvwasi == NULL || environ_count == NULL || environ_buf_size == NULL)
return UVWASI_EINVAL;
@@ -436,6 +472,14 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
int r;
#endif /* POSIX_FADV_NORMAL */
+ DEBUG("uvwasi_fd_advise(uvwasi=%p, fd=%d, offset=%"PRIu64", len=%"PRIu64", "
+ "advice=%d)\n",
+ uvwasi,
+ fd,
+ offset,
+ len,
+ advice);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
@@ -474,7 +518,7 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
return UVWASI_EINVAL;
}
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -502,10 +546,17 @@ uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_fd_allocate(uvwasi=%p, fd=%d, offset=%"PRIu64", "
+ "len=%"PRIu64")\n",
+ uvwasi,
+ fd,
+ offset,
+ len);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_ALLOCATE,
@@ -552,12 +603,14 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
uv_fs_t req;
int r;
+ DEBUG("uvwasi_fd_close(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- uvwasi_fd_table_lock(&uvwasi->fds);
+ uvwasi_fd_table_lock(uvwasi->fds);
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -570,10 +623,10 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
goto exit;
}
- err = uvwasi_fd_table_remove_nolock(uvwasi, &uvwasi->fds, fd);
+ err = uvwasi_fd_table_remove_nolock(uvwasi, uvwasi->fds, fd);
exit:
- uvwasi_fd_table_unlock(&uvwasi->fds);
+ uvwasi_fd_table_unlock(uvwasi->fds);
return err;
}
@@ -584,10 +637,12 @@ uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
uv_fs_t req;
int r;
+ DEBUG("uvwasi_fd_datasync(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_DATASYNC,
@@ -615,10 +670,12 @@ uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
int r;
#endif
+ DEBUG("uvwasi_fd_fdstat_get(uvwasi=%p, fd=%d, buf=%p)\n", uvwasi, fd, buf);
+
if (uvwasi == NULL || buf == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -646,7 +703,12 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_fdflags_t flags) {
#ifdef _WIN32
- /* TODO(cjihrig): Missing Windows support. */
+ DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n",
+ uvwasi,
+ fd,
+ flags);
+
+ /* TODO(cjihrig): Windows is not supported. */
return UVWASI_ENOSYS;
#else
struct uvwasi_fd_wrap_t* wrap;
@@ -654,10 +716,15 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
int mapped_flags;
int r;
+ DEBUG("uvwasi_fd_fdstat_set_flags(uvwasi=%p, fd=%d, flags=%d)\n",
+ uvwasi,
+ fd,
+ flags);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS,
@@ -710,10 +777,17 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
+ DEBUG("uvwasi_fd_fdstat_set_rights(uvwasi=%p, fd=%d, "
+ "fs_rights_base=%"PRIu64", fs_rights_inheriting=%"PRIu64")\n",
+ uvwasi,
+ fd,
+ fs_rights_base,
+ fs_rights_inheriting);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -746,10 +820,12 @@ uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_fd_filestat_get(uvwasi=%p, fd=%d, buf=%p)\n", uvwasi, fd, buf);
+
if (uvwasi == NULL || buf == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_FILESTAT_GET,
@@ -781,10 +857,15 @@ uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_fd_filestat_set_size(uvwasi=%p, fd=%d, st_size=%"PRIu64")\n",
+ uvwasi,
+ fd,
+ st_size);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE,
@@ -814,6 +895,14 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_fd_filestat_set_times(uvwasi=%p, fd=%d, st_atim=%"PRIu64", "
+ "st_mtim=%"PRIu64", fst_flags=%d)\n",
+ uvwasi,
+ fd,
+ st_atim,
+ st_mtim,
+ fst_flags);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
@@ -822,7 +911,7 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
return UVWASI_EINVAL;
}
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES,
@@ -845,9 +934,9 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
- size_t iovs_len,
+ uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
- size_t* nread) {
+ uvwasi_size_t* nread) {
struct uvwasi_fd_wrap_t* wrap;
uv_buf_t* bufs;
uv_fs_t req;
@@ -855,10 +944,19 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
size_t uvread;
int r;
+ DEBUG("uvwasi_fd_pread(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+ "offset=%"PRIu64", nread=%p)\n",
+ uvwasi,
+ fd,
+ iovs,
+ iovs_len,
+ offset,
+ nread);
+
if (uvwasi == NULL || iovs == NULL || nread == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_READ | UVWASI_RIGHT_FD_SEEK,
@@ -881,7 +979,7 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
if (r < 0)
return uvwasi__translate_uv_error(r);
- *nread = uvread;
+ *nread = (uvwasi_size_t) uvread;
return UVWASI_ESUCCESS;
}
@@ -892,10 +990,15 @@ uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
+ DEBUG("uvwasi_fd_prestat_get(uvwasi=%p, fd=%d, buf=%p)\n",
+ uvwasi,
+ fd,
+ buf);
+
if (uvwasi == NULL || buf == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
if (wrap->preopen != 1) {
@@ -915,15 +1018,21 @@ uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
char* path,
- size_t path_len) {
+ uvwasi_size_t path_len) {
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
size_t size;
+ DEBUG("uvwasi_fd_prestat_dir_name(uvwasi=%p, fd=%d, path=%p, path_len=%zu)\n",
+ uvwasi,
+ fd,
+ path,
+ path_len);
+
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
if (wrap->preopen != 1) {
@@ -932,7 +1041,7 @@ uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
}
size = strlen(wrap->path) + 1;
- if (size > path_len) {
+ if (size > (size_t) path_len) {
err = UVWASI_ENOBUFS;
goto exit;
}
@@ -948,9 +1057,9 @@ uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
- size_t iovs_len,
+ uvwasi_size_t iovs_len,
uvwasi_filesize_t offset,
- size_t* nwritten) {
+ uvwasi_size_t* nwritten) {
struct uvwasi_fd_wrap_t* wrap;
uv_buf_t* bufs;
uv_fs_t req;
@@ -958,10 +1067,19 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
size_t uvwritten;
int r;
+ DEBUG("uvwasi_fd_pwrite(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+ "offset=%"PRIu64", nwritten=%p)\n",
+ uvwasi,
+ fd,
+ iovs,
+ iovs_len,
+ offset,
+ nwritten);
+
if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_WRITE | UVWASI_RIGHT_FD_SEEK,
@@ -984,7 +1102,7 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
if (r < 0)
return uvwasi__translate_uv_error(r);
- *nwritten = uvwritten;
+ *nwritten = (uvwasi_size_t) uvwritten;
return UVWASI_ESUCCESS;
}
@@ -992,8 +1110,8 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
- size_t iovs_len,
- size_t* nread) {
+ uvwasi_size_t iovs_len,
+ uvwasi_size_t* nread) {
struct uvwasi_fd_wrap_t* wrap;
uv_buf_t* bufs;
uv_fs_t req;
@@ -1001,10 +1119,17 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
size_t uvread;
int r;
+ DEBUG("uvwasi_fd_read(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, nread=%p)\n",
+ uvwasi,
+ fd,
+ iovs,
+ iovs_len,
+ nread);
+
if (uvwasi == NULL || iovs == NULL || nread == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -1023,7 +1148,7 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
if (r < 0)
return uvwasi__translate_uv_error(r);
- *nread = uvread;
+ *nread = (uvwasi_size_t) uvread;
return UVWASI_ESUCCESS;
}
@@ -1031,9 +1156,9 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
void* buf,
- size_t buf_len,
+ uvwasi_size_t buf_len,
uvwasi_dircookie_t cookie,
- size_t* bufused) {
+ uvwasi_size_t* bufused) {
/* TODO(cjihrig): Support Windows where seekdir() and telldir() are used. */
/* TODO(cjihrig): Avoid opening and closing the directory on each call. */
struct uvwasi_fd_wrap_t* wrap;
@@ -1049,10 +1174,19 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
int i;
int r;
+ DEBUG("uvwasi_fd_readdir(uvwasi=%p, fd=%d, buf=%p, buf_len=%zu, "
+ "cookie=%"PRIu64", bufused=%p)\n",
+ uvwasi,
+ fd,
+ buf,
+ buf_len,
+ cookie,
+ bufused);
+
if (uvwasi == NULL || buf == NULL || bufused == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_READDIR,
@@ -1171,10 +1305,12 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
uvwasi_fd_t from,
uvwasi_fd_t to) {
+ DEBUG("uvwasi_fd_renumber(uvwasi=%p, from=%d, to=%d)\n", uvwasi, from, to);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- return uvwasi_fd_table_renumber(uvwasi, &uvwasi->fds, to, from);
+ return uvwasi_fd_table_renumber(uvwasi, uvwasi->fds, to, from);
}
@@ -1186,10 +1322,18 @@ uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
+ DEBUG("uvwasi_fd_seek(uvwasi=%p, fd=%d, offset=%"PRId64", "
+ "whence=%d, newoffset=%p)\n",
+ uvwasi,
+ fd,
+ offset,
+ whence,
+ newoffset);
+
if (uvwasi == NULL || newoffset == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -1205,10 +1349,12 @@ uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_fd_sync(uvwasi=%p, fd=%d)\n", uvwasi, fd);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_FD_SYNC,
@@ -1233,10 +1379,12 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
+ DEBUG("uvwasi_fd_tell(uvwasi=%p, fd=%d, offset=%p)\n", uvwasi, fd, offset);
+
if (uvwasi == NULL || offset == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -1249,8 +1397,8 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_ciovec_t* iovs,
- size_t iovs_len,
- size_t* nwritten) {
+ uvwasi_size_t iovs_len,
+ uvwasi_size_t* nwritten) {
struct uvwasi_fd_wrap_t* wrap;
uv_buf_t* bufs;
uv_fs_t req;
@@ -1258,10 +1406,18 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
size_t uvwritten;
int r;
+ DEBUG("uvwasi_fd_write(uvwasi=%p, fd=%d, iovs=%p, iovs_len=%zu, "
+ "nwritten=%p)\n",
+ uvwasi,
+ fd,
+ iovs,
+ iovs_len,
+ nwritten);
+
if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0);
+ err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0);
if (err != UVWASI_ESUCCESS)
return err;
@@ -1280,7 +1436,7 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
if (r < 0)
return uvwasi__translate_uv_error(r);
- *nwritten = uvwritten;
+ *nwritten = (uvwasi_size_t) uvwritten;
return UVWASI_ESUCCESS;
}
@@ -1288,17 +1444,24 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len) {
- char resolved_path[PATH_MAX_BYTES];
+ uvwasi_size_t path_len) {
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_path_create_directory(uvwasi=%p, fd=%d, path='%s', "
+ "path_len=%zu)\n",
+ uvwasi,
+ fd,
+ path,
+ path_len);
+
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_CREATE_DIRECTORY,
@@ -1306,12 +1469,13 @@ uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS)
goto exit;
r = uv_fs_mkdir(NULL, &req, resolved_path, 0777, NULL);
uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, resolved_path);
if (r != 0) {
err = uvwasi__translate_uv_error(r);
@@ -1329,18 +1493,27 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_filestat_t* buf) {
- char resolved_path[PATH_MAX_BYTES];
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_path_filestat_get(uvwasi=%p, fd=%d, flags=%d, path='%s', "
+ "path_len=%zu, buf=%p)\n",
+ uvwasi,
+ fd,
+ flags,
+ path,
+ path_len,
+ buf);
+
if (uvwasi == NULL || path == NULL || buf == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_FILESTAT_GET,
@@ -1352,12 +1525,13 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
wrap,
path,
path_len,
- resolved_path,
+ &resolved_path,
flags);
if (err != UVWASI_ESUCCESS)
goto exit;
r = uv_fs_stat(NULL, &req, resolved_path, NULL);
+ uvwasi__free(uvwasi, resolved_path);
if (r != 0) {
uv_fs_req_cleanup(&req);
err = uvwasi__translate_uv_error(r);
@@ -1377,17 +1551,28 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags) {
/* TODO(cjihrig): libuv does not currently support nanosecond precision. */
- char resolved_path[PATH_MAX_BYTES];
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_path_filestat_set_times(uvwasi=%p, fd=%d, flags=%d, path='%s', "
+ "path_len=%zu, st_atim=%"PRIu64", st_mtim=%"PRIu64", fst_flags=%d)\n",
+ uvwasi,
+ fd,
+ flags,
+ path,
+ path_len,
+ st_atim,
+ st_mtim,
+ fst_flags);
+
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;
@@ -1396,7 +1581,7 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
return UVWASI_EINVAL;
}
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES,
@@ -1408,13 +1593,14 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
wrap,
path,
path_len,
- resolved_path,
+ &resolved_path,
flags);
if (err != UVWASI_ESUCCESS)
goto exit;
/* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
r = uv_fs_utime(NULL, &req, resolved_path, st_atim, st_mtim, NULL);
+ uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);
if (r != 0) {
@@ -1433,25 +1619,36 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
uvwasi_lookupflags_t old_flags,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
- size_t new_path_len) {
- char resolved_old_path[PATH_MAX_BYTES];
- char resolved_new_path[PATH_MAX_BYTES];
+ uvwasi_size_t new_path_len) {
+ char* resolved_old_path;
+ char* resolved_new_path;
struct uvwasi_fd_wrap_t* old_wrap;
struct uvwasi_fd_wrap_t* new_wrap;
uvwasi_errno_t err;
uv_fs_t req;
int r;
+ DEBUG("uvwasi_path_link(uvwasi=%p, old_fd=%d, old_flags=%d, old_path='%s', "
+ "old_path_len=%zu, new_fd=%d, new_path='%s', new_path_len=%zu)\n",
+ uvwasi,
+ old_fd,
+ old_flags,
+ old_path,
+ old_path_len,
+ new_fd,
+ new_path,
+ new_path_len);
+
if (uvwasi == NULL || old_path == NULL || new_path == NULL)
return UVWASI_EINVAL;
- uvwasi_fd_table_lock(&uvwasi->fds);
+ uvwasi_fd_table_lock(uvwasi->fds);
if (old_fd == new_fd) {
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
old_fd,
&old_wrap,
UVWASI_RIGHT_PATH_LINK_SOURCE |
@@ -1459,17 +1656,17 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
0);
new_wrap = old_wrap;
} else {
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
old_fd,
&old_wrap,
UVWASI_RIGHT_PATH_LINK_SOURCE,
0);
if (err != UVWASI_ESUCCESS) {
- uvwasi_fd_table_unlock(&uvwasi->fds);
+ uvwasi_fd_table_unlock(uvwasi->fds);
return err;
}
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
new_fd,
&new_wrap,
UVWASI_RIGHT_PATH_LINK_TARGET,
@@ -1478,16 +1675,19 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uv_mutex_unlock(&old_wrap->mutex);
}
- uvwasi_fd_table_unlock(&uvwasi->fds);
+ uvwasi_fd_table_unlock(uvwasi->fds);
if (err != UVWASI_ESUCCESS)
return err;
+ resolved_old_path = NULL;
+ resolved_new_path = NULL;
+
err = uvwasi__resolve_path(uvwasi,
old_wrap,
old_path,
old_path_len,
- resolved_old_path,
+ &resolved_old_path,
old_flags);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -1496,7 +1696,7 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
new_wrap,
new_path,
new_path_len,
- resolved_new_path,
+ &resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -1513,6 +1713,9 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uv_mutex_unlock(&new_wrap->mutex);
if (old_fd != new_fd)
uv_mutex_unlock(&old_wrap->mutex);
+
+ uvwasi__free(uvwasi, resolved_old_path);
+ uvwasi__free(uvwasi, resolved_new_path);
return err;
}
@@ -1521,13 +1724,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_fd_t dirfd,
uvwasi_lookupflags_t dirflags,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
uvwasi_oflags_t o_flags,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting,
uvwasi_fdflags_t fs_flags,
uvwasi_fd_t* fd) {
- char resolved_path[PATH_MAX_BYTES];
+ char* resolved_path;
uvwasi_rights_t needed_inheriting;
uvwasi_rights_t needed_base;
uvwasi_rights_t max_base;
@@ -1542,6 +1745,20 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
int write;
int r;
+ DEBUG("uvwasi_path_open(uvwasi=%p, dirfd=%d, dirflags=%d, path='%s', "
+ "path_len=%zu, o_flags=%d, fs_rights_base=%"PRIu64", "
+ "fs_rights_inheriting=%"PRIu64", fs_flags=%d, fd=%p)\n",
+ uvwasi,
+ dirfd,
+ dirflags,
+ path,
+ path_len,
+ o_flags,
+ fs_rights_base,
+ fs_rights_inheriting,
+ fs_flags,
+ fd);
+
if (uvwasi == NULL || path == NULL || fd == NULL)
return UVWASI_EINVAL;
@@ -1591,7 +1808,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
if (write && (flags & (UV_FS_O_APPEND | UV_FS_O_TRUNC)) == 0)
needed_inheriting |= UVWASI_RIGHT_FD_SEEK;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
dirfd,
&dirfd_wrap,
needed_base,
@@ -1603,7 +1820,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
dirfd_wrap,
path,
path_len,
- resolved_path,
+ &resolved_path,
dirflags);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&dirfd_wrap->mutex);
@@ -1614,8 +1831,10 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uv_mutex_unlock(&dirfd_wrap->mutex);
uv_fs_req_cleanup(&req);
- if (r < 0)
+ if (r < 0) {
+ uvwasi__free(uvwasi, resolved_path);
return uvwasi__translate_uv_error(r);
+ }
/* Not all platforms support UV_FS_O_DIRECTORY, so get the file type and check
it here. */
@@ -1634,7 +1853,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
goto close_file_and_error_exit;
err = uvwasi_fd_table_insert(uvwasi,
- &uvwasi->fds,
+ uvwasi->fds,
r,
resolved_path,
resolved_path,
@@ -1648,11 +1867,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
*fd = wrap->id;
uv_mutex_unlock(&wrap->mutex);
+ uvwasi__free(uvwasi, resolved_path);
return UVWASI_ESUCCESS;
close_file_and_error_exit:
uv_fs_close(NULL, &req, r, NULL);
uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, resolved_path);
return err;
}
@@ -1660,21 +1881,31 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len,
+ uvwasi_size_t path_len,
char* buf,
- size_t buf_len,
- size_t* bufused) {
- char resolved_path[PATH_MAX_BYTES];
+ uvwasi_size_t buf_len,
+ uvwasi_size_t* bufused) {
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
uv_fs_t req;
size_t len;
int r;
+ DEBUG("uvwasi_path_readlink(uvwasi=%p, fd=%d, path='%s', path_len=%zu, "
+ "buf=%p, buf_len=%zu, bufused=%p)\n",
+ uvwasi,
+ fd,
+ path,
+ path_len,
+ buf,
+ buf_len,
+ bufused);
+
if (uvwasi == NULL || path == NULL || buf == NULL || bufused == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_READLINK,
@@ -1682,7 +1913,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
@@ -1690,6 +1921,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
r = uv_fs_readlink(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
+ uvwasi__free(uvwasi, resolved_path);
if (r != 0) {
uv_fs_req_cleanup(&req);
return uvwasi__translate_uv_error(r);
@@ -1712,17 +1944,24 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len) {
- char resolved_path[PATH_MAX_BYTES];
+ uvwasi_size_t path_len) {
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_path_remove_directory(uvwasi=%p, fd=%d, path='%s', "
+ "path_len=%zu)\n",
+ uvwasi,
+ fd,
+ path,
+ path_len);
+
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY,
@@ -1730,7 +1969,7 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
@@ -1738,6 +1977,7 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
r = uv_fs_rmdir(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
+ uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -1750,25 +1990,35 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uvwasi_fd_t old_fd,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t new_fd,
const char* new_path,
- size_t new_path_len) {
- char resolved_old_path[PATH_MAX_BYTES];
- char resolved_new_path[PATH_MAX_BYTES];
+ uvwasi_size_t new_path_len) {
+ char* resolved_old_path;
+ char* resolved_new_path;
struct uvwasi_fd_wrap_t* old_wrap;
struct uvwasi_fd_wrap_t* new_wrap;
uvwasi_errno_t err;
uv_fs_t req;
int r;
+ DEBUG("uvwasi_path_rename(uvwasi=%p, old_fd=%d, old_path='%s', "
+ "old_path_len=%zu, new_fd=%d, new_path='%s', new_path_len=%zu)\n",
+ uvwasi,
+ old_fd,
+ old_path,
+ old_path_len,
+ new_fd,
+ new_path,
+ new_path_len);
+
if (uvwasi == NULL || old_path == NULL || new_path == NULL)
return UVWASI_EINVAL;
- uvwasi_fd_table_lock(&uvwasi->fds);
+ uvwasi_fd_table_lock(uvwasi->fds);
if (old_fd == new_fd) {
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
old_fd,
&old_wrap,
UVWASI_RIGHT_PATH_RENAME_SOURCE |
@@ -1776,17 +2026,17 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
0);
new_wrap = old_wrap;
} else {
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
old_fd,
&old_wrap,
UVWASI_RIGHT_PATH_RENAME_SOURCE,
0);
if (err != UVWASI_ESUCCESS) {
- uvwasi_fd_table_unlock(&uvwasi->fds);
+ uvwasi_fd_table_unlock(uvwasi->fds);
return err;
}
- err = uvwasi_fd_table_get_nolock(&uvwasi->fds,
+ err = uvwasi_fd_table_get_nolock(uvwasi->fds,
new_fd,
&new_wrap,
UVWASI_RIGHT_PATH_RENAME_TARGET,
@@ -1795,16 +2045,19 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uv_mutex_unlock(&old_wrap->mutex);
}
- uvwasi_fd_table_unlock(&uvwasi->fds);
+ uvwasi_fd_table_unlock(uvwasi->fds);
if (err != UVWASI_ESUCCESS)
return err;
+ resolved_old_path = NULL;
+ resolved_new_path = NULL;
+
err = uvwasi__resolve_path(uvwasi,
old_wrap,
old_path,
old_path_len,
- resolved_old_path,
+ &resolved_old_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -1813,7 +2066,7 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
new_wrap,
new_path,
new_path_len,
- resolved_new_path,
+ &resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -1831,26 +2084,37 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
if (old_fd != new_fd)
uv_mutex_unlock(&old_wrap->mutex);
+ uvwasi__free(uvwasi, resolved_old_path);
+ uvwasi__free(uvwasi, resolved_new_path);
return err;
}
uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
const char* old_path,
- size_t old_path_len,
+ uvwasi_size_t old_path_len,
uvwasi_fd_t fd,
const char* new_path,
- size_t new_path_len) {
- char resolved_new_path[PATH_MAX_BYTES];
+ uvwasi_size_t new_path_len) {
+ char* resolved_new_path;
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
uv_fs_t req;
int r;
+ DEBUG("uvwasi_path_symlink(uvwasi=%p, old_path='%s', old_path_len=%zu, "
+ "fd=%d, new_path='%s', new_path_len=%zu)\n",
+ uvwasi,
+ old_path,
+ old_path_len,
+ fd,
+ new_path,
+ new_path_len);
+
if (uvwasi == NULL || old_path == NULL || new_path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_SYMLINK,
@@ -1862,7 +2126,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
wrap,
new_path,
new_path_len,
- resolved_new_path,
+ &resolved_new_path,
0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
@@ -1872,6 +2136,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
/* Windows support may require setting the flags option. */
r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL);
uv_mutex_unlock(&wrap->mutex);
+ uvwasi__free(uvwasi, resolved_new_path);
uv_fs_req_cleanup(&req);
if (r != 0)
return uvwasi__translate_uv_error(r);
@@ -1883,17 +2148,23 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
- size_t path_len) {
- char resolved_path[PATH_MAX_BYTES];
+ uvwasi_size_t path_len) {
+ char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
int r;
+ DEBUG("uvwasi_path_unlink_file(uvwasi=%p, fd=%d, path='%s', path_len=%zu)\n",
+ uvwasi,
+ fd,
+ path,
+ path_len);
+
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
+ err = uvwasi_fd_table_get(uvwasi->fds,
fd,
&wrap,
UVWASI_RIGHT_PATH_UNLINK_FILE,
@@ -1901,7 +2172,7 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
@@ -1909,6 +2180,7 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
r = uv_fs_unlink(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
+ uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -1921,14 +2193,127 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
const uvwasi_subscription_t* in,
uvwasi_event_t* out,
- size_t nsubscriptions,
- size_t* nevents) {
- /* TODO(cjihrig): Implement this. */
- return UVWASI_ENOTSUP;
+ uvwasi_size_t nsubscriptions,
+ uvwasi_size_t* nevents) {
+ struct uvwasi_poll_oneoff_state_t state;
+ struct uvwasi__poll_fdevent_t* fdevent;
+ uvwasi_userdata_t timer_userdata;
+ uvwasi_timestamp_t min_timeout;
+ uvwasi_timestamp_t cur_timeout;
+ uvwasi_timestamp_t now;
+ uvwasi_subscription_t sub;
+ uvwasi_event_t* event;
+ uvwasi_errno_t err;
+ int has_timeout;
+ uvwasi_size_t i;
+
+ DEBUG("uvwasi_poll_oneoff(uvwasi=%p, in=%p, out=%p, nsubscriptions=%zu, "
+ "nevents=%p)\n",
+ uvwasi,
+ in,
+ out,
+ nsubscriptions,
+ nevents);
+
+ if (uvwasi == NULL || in == NULL || out == NULL ||
+ nsubscriptions == 0 || nevents == NULL) {
+ return UVWASI_EINVAL;
+ }
+
+ *nevents = 0;
+ err = uvwasi__poll_oneoff_state_init(uvwasi, &state, nsubscriptions);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ has_timeout = 0;
+ min_timeout = 0;
+
+ for (i = 0; i < nsubscriptions; i++) {
+ sub = in[i];
+
+ switch (sub.type) {
+ case UVWASI_EVENTTYPE_CLOCK:
+ if (sub.u.clock.flags == UVWASI_SUBSCRIPTION_CLOCK_ABSTIME) {
+ /* Convert absolute time to relative delay. */
+ err = uvwasi__clock_gettime_realtime(&now);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ cur_timeout = sub.u.clock.timeout - now;
+ } else {
+ cur_timeout = sub.u.clock.timeout;
+ }
+
+ if (has_timeout == 0 || cur_timeout < min_timeout) {
+ min_timeout = cur_timeout;
+ timer_userdata = sub.userdata;
+ has_timeout = 1;
+ }
+
+ break;
+ case UVWASI_EVENTTYPE_FD_READ:
+ case UVWASI_EVENTTYPE_FD_WRITE:
+ err = uvwasi__poll_oneoff_state_add_fdevent(&state, &sub);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ break;
+ default:
+ err = UVWASI_EINVAL;
+ goto exit;
+ }
+ }
+
+ if (has_timeout == 1) {
+ err = uvwasi__poll_oneoff_state_set_timer(&state, min_timeout);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+ }
+
+ /* Handle poll() errors, then timeouts, then happy path. */
+ err = uvwasi__poll_oneoff_run(&state);
+ if (err != UVWASI_ESUCCESS) {
+ goto exit;
+ } else if (state.result == 0) {
+ event = &out[0];
+ event->userdata = timer_userdata;
+ event->error = UVWASI_ESUCCESS;
+ event->type = UVWASI_EVENTTYPE_CLOCK;
+ *nevents = 1;
+ } else {
+ for (i = 0; i < state.fdevent_cnt; i++) {
+ fdevent = &state.fdevents[i];
+ event = &out[*nevents];
+
+ event->userdata = fdevent->userdata;
+ event->error = fdevent->error;
+ event->type = fdevent->type;
+ event->u.fd_readwrite.nbytes = 0;
+ event->u.fd_readwrite.flags = 0;
+
+ if (fdevent->error != UVWASI_ESUCCESS)
+ ;
+ else if ((fdevent->revents & UV_DISCONNECT) != 0)
+ event->u.fd_readwrite.flags = UVWASI_EVENT_FD_READWRITE_HANGUP;
+ else if ((fdevent->revents & (UV_READABLE | UV_WRITABLE)) != 0)
+ ; /* TODO(cjihrig): Set nbytes if type is UVWASI_EVENTTYPE_FD_READ. */
+ else
+ continue;
+
+ *nevents = *nevents + 1;
+ }
+ }
+
+ err = UVWASI_ESUCCESS;
+
+exit:
+ uvwasi__poll_oneoff_state_cleanup(&state);
+ return err;
}
uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) {
+ DEBUG("uvwasi_proc_exit(uvwasi=%p, rval=%d)\n", uvwasi, rval);
exit(rval);
return UVWASI_ESUCCESS; /* This doesn't happen. */
}
@@ -1937,6 +2322,8 @@ uvwasi_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) {
uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) {
int r;
+ DEBUG("uvwasi_proc_raise(uvwasi=%p, sig=%d)\n", uvwasi, sig);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
@@ -1952,9 +2339,16 @@ uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) {
}
-uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len) {
+uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi,
+ void* buf,
+ uvwasi_size_t buf_len) {
int r;
+ DEBUG("uvwasi_random_get(uvwasi=%p, buf=%p, buf_len=%zu)\n",
+ uvwasi,
+ buf,
+ buf_len);
+
if (uvwasi == NULL || buf == NULL)
return UVWASI_EINVAL;
@@ -1967,6 +2361,8 @@ uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len) {
uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) {
+ DEBUG("uvwasi_sched_yield(uvwasi=%p)\n", uvwasi);
+
if (uvwasi == NULL)
return UVWASI_EINVAL;
@@ -1984,12 +2380,13 @@ uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) {
uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_iovec_t* ri_data,
- size_t ri_data_len,
+ uvwasi_size_t ri_data_len,
uvwasi_riflags_t ri_flags,
- size_t* ro_datalen,
+ uvwasi_size_t* ro_datalen,
uvwasi_roflags_t* ro_flags) {
/* TODO(cjihrig): Waiting to implement, pending
https://github.com/WebAssembly/WASI/issues/4 */
+ DEBUG("uvwasi_sock_recv(uvwasi=%p, unimplemented)\n", uvwasi);
return UVWASI_ENOTSUP;
}
@@ -1997,11 +2394,12 @@ uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi,
uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi,
uvwasi_fd_t sock,
const uvwasi_ciovec_t* si_data,
- size_t si_data_len,
+ uvwasi_size_t si_data_len,
uvwasi_siflags_t si_flags,
- size_t* so_datalen) {
+ uvwasi_size_t* so_datalen) {
/* TODO(cjihrig): Waiting to implement, pending
https://github.com/WebAssembly/WASI/issues/4 */
+ DEBUG("uvwasi_sock_send(uvwasi=%p, unimplemented)\n", uvwasi);
return UVWASI_ENOTSUP;
}
@@ -2011,6 +2409,7 @@ uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
uvwasi_sdflags_t how) {
/* TODO(cjihrig): Waiting to implement, pending
https://github.com/WebAssembly/WASI/issues/4 */
+ DEBUG("uvwasi_sock_shutdown(uvwasi=%p, unimplemented)\n", uvwasi);
return UVWASI_ENOTSUP;
}
diff --git a/deps/uvwasi/src/wasi_serdes.c b/deps/uvwasi/src/wasi_serdes.c
new file mode 100644
index 00000000000000..96253fc5af0623
--- /dev/null
+++ b/deps/uvwasi/src/wasi_serdes.c
@@ -0,0 +1,259 @@
+#include "wasi_serdes.h"
+#include "wasi_types.h"
+
+void uvwasi_serdes_write_uint64_t(void* ptr,
+ size_t offset,
+ uint64_t value) {
+ uvwasi_serdes_write_uint32_t(ptr, offset, (uint32_t) value);
+ uvwasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
+}
+
+void uvwasi_serdes_write_uint32_t(void* ptr,
+ size_t offset,
+ uint32_t value) {
+ uvwasi_serdes_write_uint16_t(ptr, offset, (uint16_t) value);
+ uvwasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
+}
+
+void uvwasi_serdes_write_uint16_t(void* ptr,
+ size_t offset,
+ uint16_t value) {
+ uvwasi_serdes_write_uint8_t(ptr, offset, (uint8_t) value);
+ uvwasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
+}
+
+void uvwasi_serdes_write_uint8_t(void* ptr,
+ size_t offset,
+ uint8_t value) {
+ ((uint8_t*) ptr)[offset] = value;
+}
+
+uint64_t uvwasi_serdes_read_uint64_t(const void* ptr, size_t offset) {
+ uint64_t low = uvwasi_serdes_read_uint32_t(ptr, offset);
+ uint64_t high = uvwasi_serdes_read_uint32_t(ptr, offset + 4);
+ return low | (high << 32);
+}
+
+uint32_t uvwasi_serdes_read_uint32_t(const void* ptr, size_t offset) {
+ uint32_t low = uvwasi_serdes_read_uint16_t(ptr, offset);
+ uint32_t high = uvwasi_serdes_read_uint16_t(ptr, offset + 2);
+ return low | (high << 16);
+}
+
+uint16_t uvwasi_serdes_read_uint16_t(const void* ptr, size_t offset) {
+ uint16_t low = uvwasi_serdes_read_uint8_t(ptr, offset);
+ uint16_t high = uvwasi_serdes_read_uint8_t(ptr, offset + 1);
+ return low | (high << 8);
+}
+
+uint8_t uvwasi_serdes_read_uint8_t(const void* ptr, size_t offset) {
+ return ((const uint8_t*) ptr)[offset];
+}
+
+#define TYPE_SWITCH switch (value->type)
+
+#define ALL_TYPES(STRUCT, FIELD, ALIAS) \
+ \
+ ALIAS(advice_t, uint8_t) \
+ ALIAS(clockid_t, uint32_t) \
+ ALIAS(device_t, uint64_t) \
+ ALIAS(dircookie_t, uint64_t) \
+ ALIAS(errno_t, uint16_t) \
+ ALIAS(eventrwflags_t, uint16_t) \
+ ALIAS(eventtype_t, uint8_t) \
+ ALIAS(exitcode_t, uint32_t) \
+ ALIAS(fd_t, uint32_t) \
+ ALIAS(fdflags_t, uint16_t) \
+ ALIAS(filesize_t, uint64_t) \
+ ALIAS(filetype_t, uint8_t) \
+ ALIAS(fstflags_t, uint16_t) \
+ ALIAS(inode_t, uint64_t) \
+ ALIAS(linkcount_t, uint64_t) \
+ ALIAS(lookupflags_t, uint32_t) \
+ ALIAS(oflags_t, uint16_t) \
+ ALIAS(preopentype_t, uint8_t) \
+ ALIAS(riflags_t, uint16_t) \
+ ALIAS(rights_t, uint64_t) \
+ ALIAS(roflags_t, uint16_t) \
+ ALIAS(sdflags_t, uint8_t) \
+ ALIAS(siflags_t, uint16_t) \
+ ALIAS(signal_t, uint8_t) \
+ ALIAS(size_t, uint32_t) \
+ ALIAS(subclockflags_t, uint16_t) \
+ ALIAS(timestamp_t, uint64_t) \
+ ALIAS(userdata_t, uint64_t) \
+ ALIAS(whence_t, uint8_t) \
+ \
+ STRUCT(fdstat_t) { \
+ FIELD( 0, filetype_t, fs_filetype); \
+ FIELD( 2, fdflags_t, fs_flags); \
+ FIELD( 8, rights_t, fs_rights_base); \
+ FIELD(16, rights_t, fs_rights_inheriting); \
+ } \
+ \
+ STRUCT(filestat_t) { \
+ FIELD( 0, device_t, st_dev); \
+ FIELD( 8, inode_t, st_ino); \
+ FIELD(16, filetype_t, st_filetype); \
+ FIELD(24, linkcount_t, st_nlink); \
+ FIELD(32, filesize_t, st_size); \
+ FIELD(40, timestamp_t, st_atim); \
+ FIELD(48, timestamp_t, st_mtim); \
+ FIELD(56, timestamp_t, st_ctim); \
+ } \
+ \
+ STRUCT(prestat_t) { \
+ FIELD(0, preopentype_t, pr_type); \
+ FIELD(4, uint32_t, u.dir.pr_name_len); \
+ } \
+ \
+ STRUCT(event_t) { \
+ FIELD( 0, userdata_t, userdata); \
+ FIELD( 8, errno_t, error); \
+ FIELD(10, eventtype_t, type); \
+ TYPE_SWITCH { \
+ case UVWASI_EVENTTYPE_FD_READ: \
+ case UVWASI_EVENTTYPE_FD_WRITE: \
+ FIELD(16, filesize_t, u.fd_readwrite.nbytes); \
+ FIELD(24, eventrwflags_t, u.fd_readwrite.flags); \
+ } \
+ } \
+ \
+ STRUCT(subscription_t) { \
+ FIELD(0, userdata_t, userdata); \
+ FIELD(8, eventtype_t, type); \
+ TYPE_SWITCH { \
+ case UVWASI_EVENTTYPE_CLOCK: \
+ FIELD(16, clockid_t, u.clock.clock_id); \
+ FIELD(24, timestamp_t, u.clock.timeout); \
+ FIELD(32, timestamp_t, u.clock.precision); \
+ FIELD(40, subclockflags_t, u.clock.flags); \
+ break; \
+ case UVWASI_EVENTTYPE_FD_READ: \
+ case UVWASI_EVENTTYPE_FD_WRITE: \
+ FIELD(16, fd_t, u.fd_readwrite.fd); \
+ } \
+ } \
+
+#define WRITE_STRUCT(name) \
+ void uvwasi_serdes_write_##name(void* ptr, \
+ size_t offset, \
+ const uvwasi_##name* value) \
+
+#define READ_STRUCT(name) \
+ void uvwasi_serdes_read_##name(const void* ptr, \
+ size_t offset, \
+ uvwasi_##name* value) \
+
+#define WRITE_FIELD(field_offset, type, field) \
+ do { \
+ uvwasi_serdes_write_##type(ptr, offset + field_offset, value->field); \
+ } while (0) \
+
+#define READ_FIELD(field_offset, type, field) \
+ do { \
+ value->field = uvwasi_serdes_read_##type(ptr, offset + field_offset); \
+ } while (0) \
+
+#define WRITE_ALIAS(new_name, old_name) \
+ void uvwasi_serdes_write_##new_name(void* ptr, \
+ size_t offset, \
+ uvwasi_##new_name value) { \
+ uvwasi_serdes_write_##old_name(ptr, offset, value); \
+ } \
+
+#define READ_ALIAS(new_name, old_name) \
+ uvwasi_##new_name uvwasi_serdes_read_##new_name(const void* ptr, \
+ size_t offset) { \
+ return uvwasi_serdes_read_##old_name(ptr, offset); \
+ } \
+
+ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
+ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
+
+
+uvwasi_errno_t uvwasi_serdes_read_ciovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_ciovec_t* value) {
+ uint32_t buf_ptr;
+
+ buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
+ value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
+
+ if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
+ return UVWASI_EOVERFLOW;
+
+ value->buf = ((uint8_t*) ptr + buf_ptr);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_read_iovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_iovec_t* value) {
+ uint32_t buf_ptr;
+
+ buf_ptr = uvwasi_serdes_read_uint32_t(ptr, offset);
+ value->buf_len = uvwasi_serdes_read_size_t(ptr, offset + 4);
+
+ if (!uvwasi_serdes_check_bounds(buf_ptr, end, value->buf_len))
+ return UVWASI_EOVERFLOW;
+
+ value->buf = ((uint8_t*) ptr + buf_ptr);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_readv_ciovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_ciovec_t* iovs,
+ uvwasi_size_t iovs_len) {
+ uvwasi_errno_t err;
+ uvwasi_size_t i;
+
+ for (i = 0; i < iovs_len; i++) {
+ err = uvwasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ offset += UVWASI_SERDES_SIZE_ciovec_t;
+ }
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_serdes_readv_iovec_t(const void* ptr,
+ size_t end,
+ size_t offset,
+ uvwasi_iovec_t* iovs,
+ uvwasi_size_t iovs_len) {
+ uvwasi_errno_t err;
+ uvwasi_size_t i;
+
+ for (i = 0; i < iovs_len; i++) {
+ err = uvwasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ offset += UVWASI_SERDES_SIZE_iovec_t;
+ }
+
+ return UVWASI_ESUCCESS;
+}
+
+
+int uvwasi_serdes_check_bounds(size_t offset, size_t end, size_t size) {
+ return end > offset && size <= (end - offset);
+}
+
+
+int uvwasi_serdes_check_array_bounds(size_t offset,
+ size_t end,
+ size_t size,
+ size_t count) {
+ return end > offset &&
+ ((count * size) / size == count) &&
+ (count * size <= end - offset);
+}
diff --git a/deps/uvwasi/uvwasi.gyp b/deps/uvwasi/uvwasi.gyp
index 42769095ecbafd..d4189eeee2fc94 100644
--- a/deps/uvwasi/uvwasi.gyp
+++ b/deps/uvwasi/uvwasi.gyp
@@ -12,9 +12,11 @@
'src/clocks.c',
'src/fd_table.c',
'src/path_resolver.c',
+ 'src/poll_oneoff.c',
'src/uv_mapping.c',
'src/uvwasi.c',
'src/wasi_rights.c',
+ 'src/wasi_serdes.c',
],
'dependencies': [
'../uv/uv.gyp:libuv',
diff --git a/deps/v8/.git-blame-ignore-revs b/deps/v8/.git-blame-ignore-revs
index 5ae39770316425..4c53e208e3acec 100644
--- a/deps/v8/.git-blame-ignore-revs
+++ b/deps/v8/.git-blame-ignore-revs
@@ -23,3 +23,6 @@ e50b49a0e38b34e2b28e026f4d1c7e0da0c7bb1a
# Rewrite code base to use "." instead of "->" to access Object members.
878ccb33bd3cf0e6dc018ff8d15843f585ac07be
+
+# Move test/mjsunit/regress-*.js => test/mjsunit/regress/
+cb67be1a3842fcf6a0da18aee444e3b7ea789e04
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS
index 819d147096c496..7036ecd42bc461 100644
--- a/deps/v8/AUTHORS
+++ b/deps/v8/AUTHORS
@@ -77,11 +77,13 @@ Daniel Andersson
Daniel Bevenius
Daniel James
David Carlier
+David Manouchehri
Deepak Mohan
Deon Dior
Dominic Farolini
Douglas Crosher
Dusan Milosavljevic
+Eric Rannaud
Erich Ocean
Evan Lucas
Fedor Indutny
@@ -97,12 +99,14 @@ Henrique Ferreiro
Hirofumi Mako
Honggyu Kim
Huáng Jùnliàng
+Iain Ireland
Ingvar Stepanyan
Ioseb Dzmanashvili
Isiah Meadows
Jaime Bernardo
Jan de Mooij
Jan Krems
+Janusz Majnert
Jay Freeman
James Pike
James M Snell
@@ -151,6 +155,7 @@ Oliver Dunk
Paolo Giarrusso
Patrick Gansterer
Peng Fei
+Peng-Yu Chen
Peter Rybin
Peter Varga
Peter Wong
@@ -195,6 +200,7 @@ Vladimir Krivosheev
Vladimir Shutoff
Wenlu Wang
Wiktor Garbacz
+Wouter Vermeiren
Xiaoyin Liu
Yannic Bonenberger
Yong Wang
diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn
index 13bf2b0fc344b4..b2dde3f9d70312 100644
--- a/deps/v8/BUILD.gn
+++ b/deps/v8/BUILD.gn
@@ -107,7 +107,7 @@ declare_args() {
# Enable pointer compression (sets -dV8_COMPRESS_POINTERS).
v8_enable_pointer_compression = ""
- v8_enable_31bit_smis_on_64bit_arch = true
+ v8_enable_31bit_smis_on_64bit_arch = false
# Sets -dOBJECT_PRINT.
v8_enable_object_print = ""
@@ -128,7 +128,7 @@ declare_args() {
v8_enable_concurrent_marking = true
# Sets -dV8_ARRAY_BUFFER_EXTENSION
- v8_enable_array_buffer_extension = false
+ v8_enable_array_buffer_extension = true
# Enables various testing features.
v8_enable_test_features = ""
@@ -211,6 +211,13 @@ declare_args() {
# Enable additional targets necessary for verification of torque
# file generation
v8_verify_torque_generation_invariance = false
+
+ # Disable all snapshot compression.
+ v8_enable_snapshot_compression = true
+
+ # Enable control-flow integrity features, such as pointer authentication for
+ # ARM64.
+ v8_control_flow_integrity = false
}
# Derived defaults.
@@ -270,6 +277,9 @@ assert(!v8_disable_write_barriers || v8_enable_single_generation,
assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations,
"Untrusted code mitigations are unsupported on ia32")
+assert(v8_current_cpu == "arm64" || !v8_control_flow_integrity,
+ "Control-flow integrity is only supported on arm64")
+
assert(
!v8_enable_pointer_compression || !v8_enable_shared_ro_heap,
"Pointer compression is not supported with shared read-only heap enabled")
@@ -298,6 +308,7 @@ config("internal_config") {
"//build/config/compiler:wexit_time_destructors",
":internal_config_base",
":v8_header_features",
+ ":v8_tracing_config",
]
if (is_component_build) {
@@ -305,6 +316,17 @@ config("internal_config") {
}
}
+# Should be applied to all targets that write trace events.
+config("v8_tracing_config") {
+ if (v8_use_perfetto) {
+ include_dirs = [
+ "third_party/perfetto/include",
+ "$root_gen_dir/third_party/perfetto",
+ "$root_gen_dir/third_party/perfetto/build_config",
+ ]
+ }
+}
+
# This config should be applied to code using the libplatform.
config("libplatform_config") {
include_dirs = [ "include" ]
@@ -501,6 +523,15 @@ config("features") {
if (v8_enable_regexp_interpreter_threaded_dispatch) {
defines += [ "V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH" ]
}
+ if (v8_enable_snapshot_compression) {
+ defines += [ "V8_SNAPSHOT_COMPRESSION" ]
+ }
+ if (v8_control_flow_integrity) {
+ defines += [ "V8_ENABLE_CONTROL_FLOW_INTEGRITY" ]
+ }
+ if (v8_enable_wasm_gdb_remote_debugging) {
+ defines += [ "V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING" ]
+ }
}
config("toolchain") {
@@ -543,6 +574,12 @@ config("toolchain") {
}
if (v8_current_cpu == "arm64") {
defines += [ "V8_TARGET_ARCH_ARM64" ]
+ if (v8_control_flow_integrity) {
+ # TODO(v8:10026): Enable this in src/build.
+ if (current_cpu == "arm64") {
+ cflags += [ "-mbranch-protection=standard" ]
+ }
+ }
}
# Mips64el/mipsel simulators.
@@ -618,6 +655,7 @@ config("toolchain") {
}
if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
defines += [ "V8_TARGET_ARCH_S390" ]
+ cflags += [ "-ffp-contract=off" ]
if (v8_current_cpu == "s390x") {
defines += [ "V8_TARGET_ARCH_S390X" ]
}
@@ -628,8 +666,9 @@ config("toolchain") {
}
}
if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
- defines += [ "V8_TARGET_ARCH_PPC" ]
- if (v8_current_cpu == "ppc64") {
+ if (v8_current_cpu == "ppc") {
+ defines += [ "V8_TARGET_ARCH_PPC" ]
+ } else if (v8_current_cpu == "ppc64") {
defines += [ "V8_TARGET_ARCH_PPC64" ]
}
if (host_byteorder == "little") {
@@ -1138,11 +1177,14 @@ template("run_torque") {
"bit-fields-tq.h",
"builtin-definitions-tq.h",
"interface-descriptors-tq.inc",
+ "factory-tq.cc",
+ "factory-tq.inc",
"field-offsets-tq.h",
"class-verifiers-tq.cc",
"class-verifiers-tq.h",
"enum-verifiers-tq.cc",
"objects-printer-tq.cc",
+ "objects-body-descriptors-tq-inl.h",
"class-definitions-tq.cc",
"class-definitions-tq-inl.h",
"class-definitions-tq.h",
@@ -1264,6 +1306,7 @@ v8_source_set("torque_generated_definitions") {
"$target_gen_dir/torque-generated/class-definitions-tq.cc",
"$target_gen_dir/torque-generated/class-verifiers-tq.cc",
"$target_gen_dir/torque-generated/class-verifiers-tq.h",
+ "$target_gen_dir/torque-generated/factory-tq.cc",
"$target_gen_dir/torque-generated/objects-printer-tq.cc",
]
@@ -1631,11 +1674,16 @@ v8_source_set("v8_initializers") {
### gcmole(arch:mips64el) ###
"src/builtins/mips64/builtins-mips64.cc",
]
- } else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
+ } else if (v8_current_cpu == "ppc") {
sources += [
### gcmole(arch:ppc) ###
"src/builtins/ppc/builtins-ppc.cc",
]
+ } else if (v8_current_cpu == "ppc64") {
+ sources += [
+ ### gcmole(arch:ppc64) ###
+ "src/builtins/ppc/builtins-ppc.cc",
+ ]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [
### gcmole(arch:s390) ###
@@ -1684,6 +1732,7 @@ v8_header_set("v8_headers") {
public_configs = [ ":v8_header_features" ]
sources = [
+ "include/v8-fast-api-calls.h",
"include/v8-internal.h",
"include/v8.h",
"include/v8config.h",
@@ -1865,7 +1914,6 @@ v8_compiler_sources = [
"src/compiler/memory-optimizer.cc",
"src/compiler/memory-optimizer.h",
"src/compiler/node-aux-data.h",
- "src/compiler/node-cache.cc",
"src/compiler/node-cache.h",
"src/compiler/node-marker.cc",
"src/compiler/node-marker.h",
@@ -2005,6 +2053,7 @@ v8_source_set("v8_base_without_compiler") {
### gcmole(all) ###
"$target_gen_dir/builtins-generated/bytecodes-builtins-list.h",
+ "include/v8-fast-api-calls.h",
"include/v8-inspector-protocol.h",
"include/v8-inspector.h",
"include/v8-internal.h",
@@ -2235,6 +2284,9 @@ v8_source_set("v8_base_without_compiler") {
"src/execution/messages.h",
"src/execution/microtask-queue.cc",
"src/execution/microtask-queue.h",
+ "src/execution/off-thread-isolate.cc",
+ "src/execution/off-thread-isolate.h",
+ "src/execution/pointer-authentication.h",
"src/execution/protectors-inl.h",
"src/execution/protectors.cc",
"src/execution/protectors.h",
@@ -2273,6 +2325,9 @@ v8_source_set("v8_base_without_compiler") {
"src/handles/handles-inl.h",
"src/handles/handles.cc",
"src/handles/handles.h",
+ "src/handles/local-handles-inl.h",
+ "src/handles/local-handles.cc",
+ "src/handles/local-handles.h",
"src/handles/maybe-handles-inl.h",
"src/handles/maybe-handles.h",
"src/heap/array-buffer-collector.cc",
@@ -2298,8 +2353,8 @@ v8_source_set("v8_base_without_compiler") {
"src/heap/factory-inl.h",
"src/heap/factory.cc",
"src/heap/factory.h",
- "src/heap/finalization-group-cleanup-task.cc",
- "src/heap/finalization-group-cleanup-task.h",
+ "src/heap/finalization-registry-cleanup-task.cc",
+ "src/heap/finalization-registry-cleanup-task.h",
"src/heap/gc-idle-time-handler.cc",
"src/heap/gc-idle-time-handler.h",
"src/heap/gc-tracer.cc",
@@ -2323,6 +2378,8 @@ v8_source_set("v8_base_without_compiler") {
"src/heap/item-parallel-job.h",
"src/heap/local-allocator-inl.h",
"src/heap/local-allocator.h",
+ "src/heap/local-heap.cc",
+ "src/heap/local-heap.h",
"src/heap/mark-compact-inl.h",
"src/heap/mark-compact.cc",
"src/heap/mark-compact.h",
@@ -2348,6 +2405,8 @@ v8_source_set("v8_base_without_compiler") {
"src/heap/read-only-heap.cc",
"src/heap/read-only-heap.h",
"src/heap/remembered-set.h",
+ "src/heap/safepoint.cc",
+ "src/heap/safepoint.h",
"src/heap/scavenge-job.cc",
"src/heap/scavenge-job.h",
"src/heap/scavenger-inl.h",
@@ -2448,6 +2507,7 @@ v8_source_set("v8_base_without_compiler") {
"src/logging/log-utils.h",
"src/logging/log.cc",
"src/logging/log.h",
+ "src/logging/off-thread-logger.h",
"src/numbers/bignum-dtoa.cc",
"src/numbers/bignum-dtoa.h",
"src/numbers/bignum.cc",
@@ -2690,6 +2750,7 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/tagged-impl-inl.h",
"src/objects/tagged-impl.cc",
"src/objects/tagged-impl.h",
+ "src/objects/tagged-index.h",
"src/objects/tagged-value-inl.h",
"src/objects/tagged-value.h",
"src/objects/template-objects-inl.h",
@@ -2775,6 +2836,8 @@ v8_source_set("v8_base_without_compiler") {
"src/regexp/regexp-compiler.h",
"src/regexp/regexp-dotprinter.cc",
"src/regexp/regexp-dotprinter.h",
+ "src/regexp/regexp-error.cc",
+ "src/regexp/regexp-error.h",
"src/regexp/regexp-interpreter.cc",
"src/regexp/regexp-interpreter.h",
"src/regexp/regexp-macro-assembler-arch.h",
@@ -2860,6 +2923,8 @@ v8_source_set("v8_base_without_compiler") {
"src/snapshot/serializer.cc",
"src/snapshot/serializer.h",
"src/snapshot/snapshot-common.cc",
+ "src/snapshot/snapshot-compression.cc",
+ "src/snapshot/snapshot-compression.h",
"src/snapshot/snapshot-source-sink.cc",
"src/snapshot/snapshot-source-sink.h",
"src/snapshot/snapshot.h",
@@ -2966,6 +3031,8 @@ v8_source_set("v8_base_without_compiler") {
"src/wasm/wasm-code-manager.cc",
"src/wasm/wasm-code-manager.h",
"src/wasm/wasm-constants.h",
+ "src/wasm/wasm-debug-evaluate.cc",
+ "src/wasm/wasm-debug-evaluate.h",
"src/wasm/wasm-debug.cc",
"src/wasm/wasm-engine.cc",
"src/wasm/wasm-engine.h",
@@ -3012,10 +3079,30 @@ v8_source_set("v8_base_without_compiler") {
"src/zone/zone.h",
]
+ if (!v8_control_flow_integrity) {
+ sources += [ "src/execution/pointer-authentication-dummy.h" ]
+ }
+
if (v8_enable_third_party_heap) {
sources += v8_third_party_heap_files
}
+ if (v8_enable_wasm_gdb_remote_debugging) {
+ sources += [
+ "src/debug/wasm/gdb-server/gdb-server-thread.cc",
+ "src/debug/wasm/gdb-server/gdb-server-thread.h",
+ "src/debug/wasm/gdb-server/gdb-server.cc",
+ "src/debug/wasm/gdb-server/gdb-server.h",
+ "src/debug/wasm/gdb-server/session.cc",
+ "src/debug/wasm/gdb-server/session.h",
+ "src/debug/wasm/gdb-server/target.cc",
+ "src/debug/wasm/gdb-server/target.h",
+ "src/debug/wasm/gdb-server/transport.cc",
+ "src/debug/wasm/gdb-server/transport.h",
+ "src/debug/wasm/gdb-server/util.h",
+ ]
+ }
+
if (v8_check_header_includes) {
# This file will be generated by tools/generate-header-include-checks.py
# if the "check_v8_header_includes" gclient variable is set.
@@ -3169,6 +3256,9 @@ v8_source_set("v8_base_without_compiler") {
"src/regexp/arm64/regexp-macro-assembler-arm64.h",
"src/wasm/baseline/arm64/liftoff-assembler-arm64.h",
]
+ if (v8_control_flow_integrity) {
+ sources += [ "src/execution/arm64/pointer-authentication-arm64.h" ]
+ }
if (is_win) {
sources += [
"src/diagnostics/unwinding-info-win64.cc",
@@ -3229,7 +3319,7 @@ v8_source_set("v8_base_without_compiler") {
"src/regexp/mips64/regexp-macro-assembler-mips64.h",
"src/wasm/baseline/mips64/liftoff-assembler-mips64.h",
]
- } else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
+ } else if (v8_current_cpu == "ppc") {
sources += [ ### gcmole(arch:ppc) ###
"src/codegen/ppc/assembler-ppc-inl.h",
"src/codegen/ppc/assembler-ppc.cc",
@@ -3259,6 +3349,36 @@ v8_source_set("v8_base_without_compiler") {
"src/regexp/ppc/regexp-macro-assembler-ppc.h",
"src/wasm/baseline/ppc/liftoff-assembler-ppc.h",
]
+ } else if (v8_current_cpu == "ppc64") {
+ sources += [ ### gcmole(arch:ppc64) ###
+ "src/codegen/ppc/assembler-ppc-inl.h",
+ "src/codegen/ppc/assembler-ppc.cc",
+ "src/codegen/ppc/assembler-ppc.h",
+ "src/codegen/ppc/constants-ppc.cc",
+ "src/codegen/ppc/constants-ppc.h",
+ "src/codegen/ppc/cpu-ppc.cc",
+ "src/codegen/ppc/interface-descriptors-ppc.cc",
+ "src/codegen/ppc/macro-assembler-ppc.cc",
+ "src/codegen/ppc/macro-assembler-ppc.h",
+ "src/codegen/ppc/register-ppc.h",
+ "src/compiler/backend/ppc/code-generator-ppc.cc",
+ "src/compiler/backend/ppc/instruction-codes-ppc.h",
+ "src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
+ "src/compiler/backend/ppc/instruction-selector-ppc.cc",
+ "src/compiler/backend/ppc/unwinding-info-writer-ppc.cc",
+ "src/compiler/backend/ppc/unwinding-info-writer-ppc.h",
+ "src/debug/ppc/debug-ppc.cc",
+ "src/deoptimizer/ppc/deoptimizer-ppc.cc",
+ "src/diagnostics/ppc/disasm-ppc.cc",
+ "src/diagnostics/ppc/eh-frame-ppc.cc",
+ "src/execution/ppc/frame-constants-ppc.cc",
+ "src/execution/ppc/frame-constants-ppc.h",
+ "src/execution/ppc/simulator-ppc.cc",
+ "src/execution/ppc/simulator-ppc.h",
+ "src/regexp/ppc/regexp-macro-assembler-ppc.cc",
+ "src/regexp/ppc/regexp-macro-assembler-ppc.h",
+ "src/wasm/baseline/ppc/liftoff-assembler-ppc.h",
+ ]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [ ### gcmole(arch:s390) ###
"src/codegen/s390/assembler-s390-inl.h",
@@ -3359,7 +3479,10 @@ v8_source_set("v8_base_without_compiler") {
]
}
- deps += [ "//third_party/zlib" ]
+ deps += [
+ "//third_party/zlib",
+ "//third_party/zlib/google:compression_utils_portable",
+ ]
if (v8_postmortem_support) {
sources += [ "$target_gen_dir/debug-support.cc" ]
@@ -3521,6 +3644,7 @@ v8_component("v8_libbase") {
"src/base/atomicops_internals_std.h",
"src/base/base-export.h",
"src/base/bit-field.h",
+ "src/base/bits-iterator.h",
"src/base/bits.cc",
"src/base/bits.h",
"src/base/bounded-page-allocator.cc",
@@ -3799,6 +3923,47 @@ v8_source_set("fuzzer_support") {
]
}
+v8_source_set("cppgc_base") {
+ visibility = [ ":*" ]
+
+ sources = [
+ "include/cppgc/allocation.h",
+ "include/cppgc/api-constants.h",
+ "include/cppgc/finalizer-trait.h",
+ "include/cppgc/garbage-collected.h",
+ "include/cppgc/gc-info.h",
+ "include/cppgc/heap.h",
+ "include/cppgc/platform.h",
+ "include/v8config.h",
+ "src/heap/cppgc/allocation.cc",
+ "src/heap/cppgc/gc-info-table.cc",
+ "src/heap/cppgc/gc-info-table.h",
+ "src/heap/cppgc/gc-info.cc",
+ "src/heap/cppgc/heap-inl.h",
+ "src/heap/cppgc/heap-object-header-inl.h",
+ "src/heap/cppgc/heap-object-header.cc",
+ "src/heap/cppgc/heap-object-header.h",
+ "src/heap/cppgc/heap.cc",
+ "src/heap/cppgc/heap.h",
+ "src/heap/cppgc/platform.cc",
+ "src/heap/cppgc/sanitizers.h",
+ "src/heap/cppgc/stack.cc",
+ "src/heap/cppgc/stack.h",
+ ]
+
+ if (target_cpu == "x64") {
+ if (is_win) {
+ sources += [ "src/heap/cppgc/asm/x64/push_registers_win.S" ]
+ } else {
+ sources += [ "src/heap/cppgc/asm/x64/push_registers.S" ]
+ }
+ }
+
+ configs = [ ":internal_config" ]
+
+ public_deps = [ ":v8_libbase" ]
+}
+
###############################################################################
# Produce a single static library for embedders
#
@@ -3845,6 +4010,12 @@ v8_static_library("wee8") {
]
}
+v8_static_library("cppgc") {
+ deps = [ ":cppgc_base" ]
+
+ configs = [ ":internal_config" ]
+}
+
###############################################################################
# Executables
#
@@ -4076,7 +4247,7 @@ group("v8_archive") {
if (is_fuchsia && !build_with_chromium) {
import("//build/config/fuchsia/rules.gni")
- fuchsia_package("d8_fuchsia_pkg") {
+ cr_fuchsia_package("d8_fuchsia_pkg") {
testonly = true
binary = ":d8"
package_name_override = "d8"
@@ -4136,6 +4307,15 @@ if (is_component_build) {
public_configs = [ ":external_config" ]
}
+
+ v8_component("cppgc_for_testing") {
+ testonly = true
+
+ public_deps = [ ":cppgc_base" ]
+
+ configs = [ ":internal_config" ]
+ public_configs = [ ":external_config" ]
+ }
} else {
group("v8") {
public_deps = [
@@ -4159,6 +4339,14 @@ if (is_component_build) {
public_configs = [ ":external_config" ]
}
+
+ group("cppgc_for_testing") {
+ testonly = true
+
+ public_deps = [ ":cppgc_base" ]
+
+ public_configs = [ ":external_config" ]
+ }
}
v8_executable("d8") {
@@ -4179,6 +4367,7 @@ v8_executable("d8") {
# the :external_config applied to it by virtue of depending on :v8, and
# you can't have both applied to the same target.
":internal_config_base",
+ ":v8_tracing_config",
]
deps = [
@@ -4205,7 +4394,7 @@ v8_executable("d8") {
}
if (v8_use_perfetto) {
- deps += [ "//third_party/perfetto/include/perfetto/tracing" ]
+ deps += [ "//third_party/perfetto/src/tracing:in_process_backend" ]
}
}
diff --git a/deps/v8/COMMON_OWNERS b/deps/v8/COMMON_OWNERS
index cf53fe80e0bad7..1eee48173a1576 100644
--- a/deps/v8/COMMON_OWNERS
+++ b/deps/v8/COMMON_OWNERS
@@ -29,9 +29,11 @@ petermarshall@chromium.org
rmcilroy@chromium.org
sigurds@chromium.org
solanes@chromium.org
+syg@chromium.org
szuend@chromium.org
tebbi@chromium.org
-titzer@chromium.org
ulan@chromium.org
verwaest@chromium.org
+victorgomes@chromium.org
yangguo@chromium.org
+zhin@chromium.org
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index 880ff6c4b82d59..1bc687beaf6ead 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -4,13 +4,9 @@
gclient_gn_args_file = 'v8/build/config/gclient_args.gni'
gclient_gn_args = [
- 'checkout_aemu'
]
vars = {
- # By Default, do not checkout AEMU, as it is too big, as is done in Chromium.
- 'checkout_aemu': False,
-
# Fetches only the SDK boot images which match at least one of the whitelist
# entries in a comma-separated list.
#
@@ -35,10 +31,10 @@ vars = {
'check_v8_header_includes': False,
# GN CIPD package version.
- 'gn_version': 'git_revision:97cc440d84f050f99ff0161f9414bfa2ffa38f65',
+ 'gn_version': 'git_revision:5ed3c9cc67b090d5e311e4bd2aba072173e82db9',
# luci-go CIPD package version.
- 'luci_go': 'git_revision:37a855b64d59b7f079c9a0e5368f2757099d14d3',
+ 'luci_go': 'git_revision:de73cf6c4bde86f0a9c8d54151b69b0154a398f1',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
@@ -69,10 +65,6 @@ vars = {
# and whatever else without interference from each other.
'android_sdk_sources_version': '4gxhM8E62bvZpQs7Q3d0DinQaW0RLCIefhXrQBFkNy8C',
# Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling android_sdk_tools_version
- # and whatever else without interference from each other.
- 'android_sdk_tools_version': 'wYcRQC2WHsw2dKWs4EA7fw9Qsyzu1ds1_fRjKmGxe5QC',
- # Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_tools-lint_version
# and whatever else without interference from each other.
'android_sdk_tools-lint_version': '89hXqZYzCum3delB5RV7J_QyWkaRodqdtQS0s3LMh3wC',
@@ -80,15 +72,15 @@ vars = {
deps = {
'v8/build':
- Var('chromium_url') + '/chromium/src/build.git' + '@' + '2f17606c25956e800b6c4670c294a03620e78551',
+ Var('chromium_url') + '/chromium/src/build.git' + '@' + '26e9d485d01d6e0eb9dadd21df767a63494c8fea',
'v8/third_party/depot_tools':
- Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'ea8b58b970c0c94b4a36270b806ee307547cd77e',
+ Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '2b2aec6506a810f8d7bd018609de2c2450b3c121',
'v8/third_party/icu':
- Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'dbd3825b31041d782c5b504c59dcfb5ac7dda08c',
+ Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'd7aff76cf6bb0fbef3afa6c07718f78a80a70f8f',
'v8/third_party/instrumented_libraries':
Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'bb3f1802c237dd19105dd0f7919f99e536a39d10',
'v8/buildtools':
- Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + 'afc5b798c72905e85f9991152be878714c579958',
+ Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '7977eb176752aeec29d888cfe8e677ac12ed1c41',
'v8/buildtools/clang_format/script':
Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917',
'v8/buildtools/linux64': {
@@ -112,11 +104,11 @@ deps = {
'condition': 'host_os == "mac"',
},
'v8/buildtools/third_party/libc++/trunk':
- Var('chromium_url') + '/chromium/llvm-project/libcxx.git' + '@' + '78d6a7767ed57b50122a161b91f59f19c9bd0d19',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + 'd9040c75cfea5928c804ab7c235fed06a63f743a',
'v8/buildtools/third_party/libc++abi/trunk':
- Var('chromium_url') + '/chromium/llvm-project/libcxxabi.git' + '@' + '0d529660e32d77d9111912d73f2c74fc5fa2a858',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + '196ba1aaa8ac285d94f4ea8d9836390a45360533',
'v8/buildtools/third_party/libunwind/trunk':
- Var('chromium_url') + '/external/llvm.org/libunwind.git' + '@' + '69d9b84cca8354117b9fe9705a4430d789ee599b',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '43bb9f872232f531bac80093ceb4de61c64b9ab7',
'v8/buildtools/win': {
'packages': [
{
@@ -128,7 +120,7 @@ deps = {
'condition': 'host_os == "win"',
},
'v8/base/trace_event/common':
- Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'bd79231eb1f9e7de2efb4ad79e530d9a7e70d9a5',
+ Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'dab187b372fc17e51f5b9fad8201813d0aed5129',
'v8/third_party/android_ndk': {
'url': Var('chromium_url') + '/android_ndk.git' + '@' + '27c0a8d090c666a50e40fceb4ee5b40b1a2d3f87',
'condition': 'checkout_android',
@@ -167,10 +159,6 @@ deps = {
'package': 'chromium/third_party/android_sdk/public/sources/android-29',
'version': Var('android_sdk_sources_version'),
},
- {
- 'package': 'chromium/third_party/android_sdk/public/tools',
- 'version': Var('android_sdk_tools_version'),
- },
{
'package': 'chromium/third_party/android_sdk/public/tools-lint',
'version': Var('android_sdk_tools-lint_version'),
@@ -180,7 +168,7 @@ deps = {
'dep_type': 'cipd',
},
'v8/third_party/catapult': {
- 'url': Var('chromium_url') + '/catapult.git' + '@' + '2e0a0cb9ad546be8c835e65d7537507cb7896e03',
+ 'url': Var('chromium_url') + '/catapult.git' + '@' + '032c78376792ef343ea361bca2181ba6dec6b95f',
'condition': 'checkout_android',
},
'v8/third_party/colorama/src': {
@@ -188,23 +176,23 @@ deps = {
'condition': 'checkout_android',
},
'v8/third_party/fuchsia-sdk': {
- 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '19c8ac5e150fbd147ec5987425a41aa9e97098b2',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '2457e41d8dc379f74662d3157e76339ba92cee06',
'condition': 'checkout_fuchsia',
},
'v8/third_party/googletest/src':
- Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '306f3754a71d6d1ac644681d3544d06744914228',
+ Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '10b1902d893ea8cc43c69541d70868f91af3646b',
'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' + '@' + '885b3febcc170a60f25795304e60927b77d1e92d',
+ Var('chromium_url') + '/infra/luci/client-py.git' + '@' + 'cc958279ffd6853e0a1b227a7e957ca334fe56af',
'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' + '@' + '28b4fcca4b1b1d278dfe0cc0e69c7d9d59b31aab',
+ Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'f6b2ccdd091ff82da54150796297c3a96d7edb41',
'v8/test/test262/harness':
Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b',
'v8/third_party/qemu-linux-x64': {
@@ -227,8 +215,28 @@ deps = {
'condition': 'host_os == "mac" and checkout_fuchsia',
'dep_type': 'cipd',
},
+ 'v8/third_party/aemu-linux-x64': {
+ 'packages': [
+ {
+ 'package': 'fuchsia/third_party/aemu/linux-amd64',
+ 'version': '7YlCgase5GlIanqHn-nZClSlZ5kQETJyVUYRF7Jjy6UC'
+ },
+ ],
+ 'condition': 'host_os == "linux" and checkout_fuchsia',
+ 'dep_type': 'cipd',
+ },
+ 'v8/third_party/aemu-mac-x64': {
+ 'packages': [
+ {
+ 'package': 'fuchsia/third_party/aemu/mac-amd64',
+ 'version': 'T9bWxf8aUC5TwCFgPxpuW29Mfy-7Z9xCfXB9QO8MfU0C'
+ },
+ ],
+ 'condition': 'host_os == "mac" and checkout_fuchsia',
+ 'dep_type': 'cipd',
+ },
'v8/tools/clang':
- Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '535dbf16a84c7fc238f7ed11b5a75381407e38f6',
+ Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '105a8460911176861a422738eee4daad8dfe88a2',
'v8/tools/luci-go': {
'packages': [
{
@@ -258,11 +266,11 @@ deps = {
'dep_type': 'cipd',
},
'v8/third_party/perfetto':
- Var('android_url') + '/platform/external/perfetto.git' + '@' + '12dc10e0278cded35205cf84f80a821348cb6c56',
+ Var('android_url') + '/platform/external/perfetto.git' + '@' + 'b9b24d1b0b80aafec393af085067e9eae829412f',
'v8/third_party/protobuf':
Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91',
'v8/third_party/zlib':
- Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + 'b9b9a5af7cca2e683e5f2aead8418e5bf9d5a7d5',
+ Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '156be8c52f80cde343088b4a69a80579101b6e67',
'v8/third_party/ittapi': {
# Force checkout ittapi libraries to pass v8 header includes check on
# bots that has check_v8_header_includes enabled.
diff --git a/deps/v8/base/trace_event/common/trace_event_common.h b/deps/v8/base/trace_event/common/trace_event_common.h
index 3f741d816f722d..a7bffbdbeb44c7 100644
--- a/deps/v8/base/trace_event/common/trace_event_common.h
+++ b/deps/v8/base/trace_event/common/trace_event_common.h
@@ -61,28 +61,30 @@
// current process id, thread id, and a timestamp in microseconds.
//
// To trace an asynchronous procedure such as an IPC send/receive, use
-// ASYNC_BEGIN and ASYNC_END:
+// NESTABLE_ASYNC_BEGIN and NESTABLE_ASYNC_END:
// [single threaded sender code]
// static int send_count = 0;
// ++send_count;
-// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
+// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+// "ipc", "message", TRACE_ID_LOCAL(send_count));
// Send(new MyMessage(send_count));
// [receive code]
// void OnMyMessage(send_count) {
-// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
+// TRACE_NESTABLE_EVENT_ASYNC_END0(
+// "ipc", "message", TRACE_ID_LOCAL(send_count));
// }
-// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
-// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
-// Pointers can be used for the ID parameter, and they will be annotated
-// internally so that the same pointer on two different processes will not
-// match. For example:
+// The third parameter is a unique ID to match NESTABLE_ASYNC_BEGIN/ASYNC_END
+// pairs. NESTABLE_ASYNC_BEGIN and ASYNC_END can occur on any thread of any
+// traced process. // Pointers can be used for the ID parameter, and they will
+// be annotated internally so that the same pointer on two different processes
+// will not match. For example:
// class MyTracedClass {
// public:
// MyTracedClass() {
-// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
+// TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("category", "MyTracedClass", this);
// }
// ~MyTracedClass() {
-// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
+// TRACE_EVENT_NESTABLE_ASYNC_END0("category", "MyTracedClass", this);
// }
// }
//
@@ -512,9 +514,11 @@
name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
arg1_val)
-// ASYNC_STEP_* APIs should be only used by legacy code. New code should
-// consider using NESTABLE_ASYNC_* APIs to describe substeps within an async
-// event.
+// -- TRACE_EVENT_ASYNC is DEPRECATED! --
+//
+// TRACE_EVENT_ASYNC_* APIs should be only used by legacy code. New code should
+// use TRACE_EVENT_NESTABLE_ASYNC_* APIs instead.
+//
// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
// associated arguments. If the category is not enabled, then this
// does nothing.
@@ -566,9 +570,6 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
- category_group, name, id, flags)
// Similar to TRACE_EVENT_ASYNC_BEGINx but with a custom |at| timestamp
// provided.
@@ -595,11 +596,6 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \
- category_group, name, id, timestamp, flags) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
// Records a single ASYNC_STEP_INTO event for |step| immediately. If the
// category is not enabled, then this does nothing. The |name| and |id| must
@@ -671,9 +667,6 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
-#define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
- category_group, name, id, flags)
// Similar to TRACE_EVENT_ASYNC_ENDx but with a custom |at| timestamp provided.
#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
@@ -699,11 +692,6 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \
- id, timestamp, flags) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, \
- TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
// NESTABLE_ASYNC_* APIs are used to describe an async operation, which can
// be nested within a NESTABLE_ASYNC event and/or have inner NESTABLE_ASYNC
@@ -742,6 +730,10 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \
+ flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+ category_group, name, id, flags)
// Records a single NESTABLE_ASYNC_END event called "name" immediately, with 0
// or 2 associated arguments. If the category is not enabled, then this does
// nothing.
@@ -761,6 +753,10 @@
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \
+ flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+ category_group, name, id, flags)
// Records a single NESTABLE_ASYNC_INSTANT event called "name" immediately,
// with none, one or two associated argument. If the category is not enabled,
@@ -808,6 +804,11 @@
TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \
+ category_group, name, id, timestamp, flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
id, timestamp) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
@@ -826,6 +827,11 @@
TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0( \
+ category_group, name, id, timestamp, flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0( \
category_group, name, id, timestamp) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
diff --git a/deps/v8/gni/proto_library.gni b/deps/v8/gni/proto_library.gni
index b16d8f93bd8fcd..eca3ffb84e55ac 100644
--- a/deps/v8/gni/proto_library.gni
+++ b/deps/v8/gni/proto_library.gni
@@ -124,9 +124,13 @@ template("proto_library") {
rebase_path(proto_in_dir, root_build_dir),
]
if (generate_cc) {
+ cc_generator_options_ = ""
+ if (defined(invoker.cc_generator_options)) {
+ cc_generator_options_ = invoker.cc_generator_options
+ }
args += [
"--cpp_out",
- rel_cc_out_dir,
+ cc_generator_options_ + rel_cc_out_dir,
]
}
if (generate_descriptor != "") {
@@ -153,13 +157,9 @@ template("proto_library") {
args += rebase_path(proto_sources, root_build_dir)
- inputs = [
- protoc_path,
- ]
+ inputs = [ protoc_path ]
- deps = [
- protoc_label,
- ]
+ deps = [ protoc_label ]
if (generate_with_plugin) {
inputs += [ plugin_path ]
if (defined(plugin_host_label)) {
@@ -201,21 +201,23 @@ template("proto_library") {
public_configs = []
}
- public_configs += [
- "//:protobuf_gen_config",
- ":$config_name",
- ]
+ public_configs += [ "//:protobuf_gen_config" ]
+
+ propagate_imports_configs = !defined(invoker.propagate_imports_configs) ||
+ invoker.propagate_imports_configs
+ if (propagate_imports_configs) {
+ public_configs += [ ":$config_name" ]
+ } else {
+ # Embedder handles include directory propagation to dependents.
+ configs += [ ":$config_name" ]
+ }
# Use protobuf_full only for tests.
if (defined(invoker.use_protobuf_full) &&
invoker.use_protobuf_full == true) {
- deps = [
- "//:protobuf_full",
- ]
+ deps = [ "//:protobuf_full" ]
} else {
- deps = [
- "//:protobuf_lite",
- ]
+ deps = [ "//:protobuf_lite" ]
}
deps += [ ":$action_name" ]
diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni
index eaf76a471b3395..0b2806ca949b77 100644
--- a/deps/v8/gni/v8.gni
+++ b/deps/v8/gni/v8.gni
@@ -57,6 +57,12 @@ declare_args() {
# Use Perfetto (https://perfetto.dev) as the default TracingController. Not
# currently implemented.
v8_use_perfetto = false
+
+ # Override global symbol level setting for v8
+ v8_symbol_level = symbol_level
+
+ # Enable WebAssembly debugging via GDB-remote protocol.
+ v8_enable_wasm_gdb_remote_debugging = false
}
if (v8_use_external_startup_data == "") {
@@ -109,6 +115,13 @@ if (is_debug && !v8_optimized_debug) {
}
}
+if (!is_debug) {
+ v8_remove_configs += [
+ # Too much performance impact, unclear security benefit.
+ "//build/config/compiler:default_init_stack_vars",
+ ]
+}
+
if (v8_code_coverage && !is_clang) {
v8_add_configs += [
v8_path_prefix + ":v8_gcov_coverage_cflags",
@@ -116,6 +129,19 @@ if (v8_code_coverage && !is_clang) {
]
}
+if (v8_symbol_level != symbol_level) {
+ v8_remove_configs += [ "//build/config/compiler:default_symbols" ]
+ if (v8_symbol_level == 0) {
+ v8_add_configs += [ "//build/config/compiler:no_symbols" ]
+ } else if (v8_symbol_level == 1) {
+ v8_add_configs += [ "//build/config/compiler:minimal_symbols" ]
+ } else if (v8_symbol_level == 2) {
+ v8_add_configs += [ "//build/config/compiler:symbols" ]
+ } else {
+ assert(false)
+ }
+}
+
if ((is_posix || is_fuchsia) &&
(v8_enable_backtrace || v8_monolithic || v8_expose_symbols)) {
v8_remove_configs += [ "//build/config/gcc:symbol_visibility_hidden" ]
@@ -217,6 +243,25 @@ template("v8_component") {
}
}
+template("v8_shared_library") {
+ shared_library(target_name) {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "configs",
+ "remove_configs",
+ ])
+ configs -= v8_remove_configs
+ configs += v8_add_configs
+ if (defined(invoker.remove_configs)) {
+ configs -= invoker.remove_configs
+ }
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ }
+}
+
template("v8_static_library") {
static_library(target_name) {
complete_static_lib = true
diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS
index 1e0794df7a2796..4f90a5c8c70692 100644
--- a/deps/v8/include/OWNERS
+++ b/deps/v8/include/OWNERS
@@ -1,5 +1,6 @@
adamk@chromium.org
danno@chromium.org
+mlippautz@chromium.org
ulan@chromium.org
verwaest@chromium.org
yangguo@chromium.org
diff --git a/deps/v8/include/cppgc/README.md b/deps/v8/include/cppgc/README.md
new file mode 100644
index 00000000000000..3a2db6dfa97ece
--- /dev/null
+++ b/deps/v8/include/cppgc/README.md
@@ -0,0 +1,5 @@
+# C++ Garbage Collection
+
+This directory provides an open-source garbage collection library for C++.
+
+The library is under construction, meaning that *all APIs in this directory are incomplete and considered unstable and should not be used*.
\ No newline at end of file
diff --git a/deps/v8/include/cppgc/allocation.h b/deps/v8/include/cppgc/allocation.h
new file mode 100644
index 00000000000000..3e717ad7d428f8
--- /dev/null
+++ b/deps/v8/include/cppgc/allocation.h
@@ -0,0 +1,91 @@
+// Copyright 2020 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 INCLUDE_CPPGC_ALLOCATION_H_
+#define INCLUDE_CPPGC_ALLOCATION_H_
+
+#include
+#include
+
+#include "include/cppgc/garbage-collected.h"
+#include "include/cppgc/gc-info.h"
+#include "include/cppgc/heap.h"
+#include "include/cppgc/internals.h"
+
+namespace cppgc {
+
+template
+class MakeGarbageCollectedTraitBase;
+
+namespace internal {
+
+class V8_EXPORT MakeGarbageCollectedTraitInternal {
+ protected:
+ static inline void MarkObjectAsFullyConstructed(const void* payload) {
+ // See api_constants for an explanation of the constants.
+ std::atomic* atomic_mutable_bitfield =
+ reinterpret_cast*>(
+ const_cast(reinterpret_cast(
+ reinterpret_cast(payload) -
+ api_constants::kFullyConstructedBitFieldOffsetFromPayload)));
+ uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
+ value = value | api_constants::kFullyConstructedBitMask;
+ atomic_mutable_bitfield->store(value, std::memory_order_release);
+ }
+
+ static void* Allocate(cppgc::Heap* heap, size_t size, GCInfoIndex index);
+
+ friend class HeapObjectHeader;
+};
+
+} // namespace internal
+
+// Users with custom allocation needs (e.g. overriding size) should override
+// MakeGarbageCollectedTrait (see below) and inherit their trait from
+// MakeGarbageCollectedTraitBase to get access to low-level primitives.
+template
+class MakeGarbageCollectedTraitBase
+ : private internal::MakeGarbageCollectedTraitInternal {
+ protected:
+ // Allocates an object of |size| bytes on |heap|.
+ //
+ // TODO(mlippautz): Allow specifying arena for specific embedder uses.
+ static void* Allocate(Heap* heap, size_t size) {
+ return internal::MakeGarbageCollectedTraitInternal::Allocate(
+ heap, size, internal::GCInfoTrait::Index());
+ }
+
+ // Marks an object as being fully constructed, resulting in precise handling
+ // by the garbage collector.
+ static void MarkObjectAsFullyConstructed(const void* payload) {
+ // internal::MarkObjectAsFullyConstructed(payload);
+ internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed(
+ payload);
+ }
+};
+
+template
+class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase {
+ public:
+ template
+ static T* Call(Heap* heap, Args&&... args) {
+ static_assert(internal::IsGarbageCollectedType::value,
+ "T needs to be a garbage collected object");
+ void* memory = MakeGarbageCollectedTraitBase::Allocate(heap, sizeof(T));
+ T* object = ::new (memory) T(std::forward(args)...);
+ MakeGarbageCollectedTraitBase::MarkObjectAsFullyConstructed(object);
+ return object;
+ }
+};
+
+// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
+// collected type.
+template
+T* MakeGarbageCollected(Heap* heap, Args&&... args) {
+ return MakeGarbageCollectedTrait::Call(heap, std::forward(args)...);
+}
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_ALLOCATION_H_
diff --git a/deps/v8/include/cppgc/finalizer-trait.h b/deps/v8/include/cppgc/finalizer-trait.h
new file mode 100644
index 00000000000000..12216ed84ed9f6
--- /dev/null
+++ b/deps/v8/include/cppgc/finalizer-trait.h
@@ -0,0 +1,90 @@
+// Copyright 2020 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 INCLUDE_CPPGC_FINALIZER_TRAIT_H_
+#define INCLUDE_CPPGC_FINALIZER_TRAIT_H_
+
+#include
+
+#include "include/cppgc/internals.h"
+
+namespace cppgc {
+namespace internal {
+
+using FinalizationCallback = void (*)(void*);
+
+template
+struct HasFinalizeGarbageCollectedObject : std::false_type {};
+
+template
+struct HasFinalizeGarbageCollectedObject<
+ T, void_t().FinalizeGarbageCollectedObject())>>
+ : std::true_type {};
+
+// The FinalizerTraitImpl specifies how to finalize objects.
+template
+struct FinalizerTraitImpl;
+
+template
+struct FinalizerTraitImpl {
+ private:
+ // Dispatch to custom FinalizeGarbageCollectedObject().
+ struct Custom {
+ static void Call(void* obj) {
+ static_cast(obj)->FinalizeGarbageCollectedObject();
+ }
+ };
+
+ // Dispatch to regular destructor.
+ struct Destructor {
+ static void Call(void* obj) { static_cast(obj)->~T(); }
+ };
+
+ using FinalizeImpl =
+ std::conditional_t::value, Custom,
+ Destructor>;
+
+ public:
+ static void Finalize(void* obj) {
+ static_assert(sizeof(T), "T must be fully defined");
+ FinalizeImpl::Call(obj);
+ }
+};
+
+template
+struct FinalizerTraitImpl {
+ static void Finalize(void* obj) {
+ static_assert(sizeof(T), "T must be fully defined");
+ }
+};
+
+// The FinalizerTrait is used to determine if a type requires finalization and
+// what finalization means.
+template
+struct FinalizerTrait {
+ private:
+ // Object has a finalizer if it has
+ // - a custom FinalizeGarbageCollectedObject method, or
+ // - a destructor.
+ static constexpr bool kNonTrivialFinalizer =
+ internal::HasFinalizeGarbageCollectedObject::value ||
+ !std::is_trivially_destructible::type>::value;
+
+ static void Finalize(void* obj) {
+ internal::FinalizerTraitImpl::Finalize(obj);
+ }
+
+ public:
+ // The callback used to finalize an object of type T.
+ static constexpr FinalizationCallback kCallback =
+ kNonTrivialFinalizer ? Finalize : nullptr;
+};
+
+template
+constexpr FinalizationCallback FinalizerTrait::kCallback;
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_FINALIZER_TRAIT_H_
diff --git a/deps/v8/include/cppgc/garbage-collected.h b/deps/v8/include/cppgc/garbage-collected.h
new file mode 100644
index 00000000000000..6c62daafdc5d8d
--- /dev/null
+++ b/deps/v8/include/cppgc/garbage-collected.h
@@ -0,0 +1,53 @@
+// Copyright 2020 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 INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
+#define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
+
+#include
+
+#include "include/cppgc/internals.h"
+#include "include/cppgc/platform.h"
+
+namespace cppgc {
+namespace internal {
+
+template
+struct IsGarbageCollectedType : std::false_type {
+ static_assert(sizeof(T), "T must be fully defined");
+};
+
+template
+struct IsGarbageCollectedType<
+ T, void_t::IsGarbageCollectedTypeMarker>>
+ : std::true_type {
+ static_assert(sizeof(T), "T must be fully defined");
+};
+
+} // namespace internal
+
+template
+class GarbageCollected {
+ public:
+ using IsGarbageCollectedTypeMarker = void;
+
+ // Must use MakeGarbageCollected.
+ void* operator new(size_t) = delete;
+ void* operator new[](size_t) = delete;
+ // The garbage collector is taking care of reclaiming the object. Also,
+ // virtual destructor requires an unambiguous, accessible 'operator delete'.
+ void operator delete(void*) {
+#ifdef V8_ENABLE_CHECKS
+ internal::Abort();
+#endif // V8_ENABLE_CHECKS
+ }
+ void operator delete[](void*) = delete;
+
+ protected:
+ GarbageCollected() = default;
+};
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
diff --git a/deps/v8/include/cppgc/gc-info.h b/deps/v8/include/cppgc/gc-info.h
new file mode 100644
index 00000000000000..987ba34fa4254c
--- /dev/null
+++ b/deps/v8/include/cppgc/gc-info.h
@@ -0,0 +1,43 @@
+// Copyright 2020 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 INCLUDE_CPPGC_GC_INFO_H_
+#define INCLUDE_CPPGC_GC_INFO_H_
+
+#include
+
+#include "include/cppgc/finalizer-trait.h"
+#include "include/v8config.h"
+
+namespace cppgc {
+namespace internal {
+
+using GCInfoIndex = uint16_t;
+
+class V8_EXPORT RegisteredGCInfoIndex final {
+ public:
+ RegisteredGCInfoIndex(FinalizationCallback finalization_callback,
+ bool has_v_table);
+ GCInfoIndex GetIndex() const { return index_; }
+
+ private:
+ const GCInfoIndex index_;
+};
+
+// Trait determines how the garbage collector treats objects wrt. to traversing,
+// finalization, and naming.
+template
+struct GCInfoTrait {
+ static GCInfoIndex Index() {
+ static_assert(sizeof(T), "T must be fully defined");
+ static const RegisteredGCInfoIndex registered_index(
+ FinalizerTrait::kCallback, std::is_polymorphic::value);
+ return registered_index.GetIndex();
+ }
+};
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_GC_INFO_H_
diff --git a/deps/v8/include/cppgc/heap.h b/deps/v8/include/cppgc/heap.h
new file mode 100644
index 00000000000000..a0568d534fbee2
--- /dev/null
+++ b/deps/v8/include/cppgc/heap.h
@@ -0,0 +1,31 @@
+// Copyright 2020 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 INCLUDE_CPPGC_HEAP_H_
+#define INCLUDE_CPPGC_HEAP_H_
+
+#include
+
+#include "include/v8config.h"
+
+namespace cppgc {
+namespace internal {
+class Heap;
+} // namespace internal
+
+class V8_EXPORT Heap {
+ public:
+ static std::unique_ptr Create();
+
+ virtual ~Heap() = default;
+
+ private:
+ Heap() = default;
+
+ friend class internal::Heap;
+};
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_HEAP_H_
diff --git a/deps/v8/include/cppgc/internals.h b/deps/v8/include/cppgc/internals.h
new file mode 100644
index 00000000000000..1e57779758b6c7
--- /dev/null
+++ b/deps/v8/include/cppgc/internals.h
@@ -0,0 +1,41 @@
+// Copyright 2020 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 INCLUDE_CPPGC_INTERNALS_H_
+#define INCLUDE_CPPGC_INTERNALS_H_
+
+#include
+#include
+
+#include "include/v8config.h"
+
+namespace cppgc {
+namespace internal {
+
+// Pre-C++17 custom implementation of std::void_t.
+template
+struct make_void {
+ typedef void type;
+};
+template
+using void_t = typename make_void::type;
+
+// Embedders should not rely on this code!
+
+// Internal constants to avoid exposing internal types on the API surface.
+namespace api_constants {
+// Offset of the uint16_t bitfield from the payload contaning the
+// in-construction bit. This is subtracted from the payload pointer to get
+// to the right bitfield.
+static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload =
+ 2 * sizeof(uint16_t);
+// Mask for in-construction bit.
+static constexpr size_t kFullyConstructedBitMask = size_t{1};
+
+} // namespace api_constants
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNALS_H_
diff --git a/deps/v8/include/cppgc/platform.h b/deps/v8/include/cppgc/platform.h
new file mode 100644
index 00000000000000..f216c2730a4dea
--- /dev/null
+++ b/deps/v8/include/cppgc/platform.h
@@ -0,0 +1,31 @@
+// Copyright 2020 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 INCLUDE_CPPGC_PLATFORM_H_
+#define INCLUDE_CPPGC_PLATFORM_H_
+
+#include "include/v8-platform.h"
+#include "include/v8config.h"
+
+namespace cppgc {
+
+// TODO(v8:10346): Put PageAllocator in a non-V8 include header to avoid
+// depending on namespace v8.
+using PageAllocator = v8::PageAllocator;
+
+// Initializes the garbage collector with the provided platform. Must be called
+// before creating a Heap.
+V8_EXPORT void InitializePlatform(PageAllocator* page_allocator);
+
+// Must be called after destroying the last used heap.
+V8_EXPORT void ShutdownPlatform();
+
+namespace internal {
+
+V8_EXPORT void Abort();
+
+} // namespace internal
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_PLATFORM_H_
diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl
index 28b8e610767142..3f5410d1e1f787 100644
--- a/deps/v8/include/js_protocol.pdl
+++ b/deps/v8/include/js_protocol.pdl
@@ -119,6 +119,7 @@ domain Debugger
script
eval
module
+ wasm-expression-stack
# Object representing the scope. For `global` and `with` scopes it represents the actual
# object; for the rest of the scopes, it is artificial transient object enumerating scope
# variables as its properties.
@@ -273,6 +274,13 @@ domain Debugger
# Resumes JavaScript execution.
command resume
+ parameters
+ # Set to true to terminate execution upon resuming execution. In contrast
+ # to Runtime.terminateExecution, this will allows to execute further
+ # JavaScript (i.e. via evaluation) until execution of the paused code
+ # is actually resumed, at which point termination is triggered.
+ # If execution is currently not paused, this parameter has no effect.
+ optional boolean terminateOnResume
# Searches for given string in script content.
command searchInContent
@@ -496,6 +504,12 @@ domain Debugger
# Fired when the virtual machine resumed execution.
event resumed
+ # Enum of possible script languages.
+ type ScriptLanguage extends string
+ enum
+ JavaScript
+ WebAssembly
+
# Fired when virtual machine fails to parse the script.
event scriptFailedToParse
parameters
@@ -527,6 +541,10 @@ domain Debugger
optional integer length
# JavaScript top stack frame of where the script parsed event was triggered if available.
experimental optional Runtime.StackTrace stackTrace
+ # If the scriptLanguage is WebAssembly, the code section offset in the module.
+ experimental optional integer codeOffset
+ # The language of the script.
+ experimental optional Debugger.ScriptLanguage scriptLanguage
# Fired when virtual machine parses script. This event is also fired for all known and uncollected
# scripts upon enabling debugger.
@@ -562,6 +580,10 @@ domain Debugger
optional integer length
# JavaScript top stack frame of where the script parsed event was triggered if available.
experimental optional Runtime.StackTrace stackTrace
+ # If the scriptLanguage is WebAssembly, the code section offset in the module.
+ experimental optional integer codeOffset
+ # The language of the script.
+ experimental optional Debugger.ScriptLanguage scriptLanguage
experimental domain HeapProfiler
depends on Runtime
@@ -824,6 +846,8 @@ domain Profiler
optional boolean callCount
# Collect block-based coverage.
optional boolean detailed
+ # Allow the backend to send updates on its own initiative
+ optional boolean allowTriggeredUpdates
returns
# Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
number timestamp
@@ -931,7 +955,8 @@ domain Runtime
boolean
symbol
bigint
- # Object subtype hint. Specified for `object` type values only.
+ wasm
+ # Object subtype hint. Specified for `object` or `wasm` type values only.
optional enum subtype
array
null
@@ -950,6 +975,11 @@ domain Runtime
typedarray
arraybuffer
dataview
+ i32
+ i64
+ f32
+ f64
+ v128
# Object class (constructor) name. Specified for `object` type values only.
optional string className
# Remote object value in case of primitive values or JSON values (if it was requested).
@@ -1306,7 +1336,9 @@ domain Runtime
experimental optional TimeDelta timeout
# Disable breakpoints during execution.
experimental optional boolean disableBreaks
- # Reserved flag for future REPL mode support. Setting this flag has currently no effect.
+ # Setting this flag to true enables `let` re-declaration and top-level `await`.
+ # Note that `let` variables can only be re-declared if they originate from
+ # `replMode` themselves.
experimental optional boolean replMode
returns
# Evaluation result.
diff --git a/deps/v8/include/v8-fast-api-calls.h b/deps/v8/include/v8-fast-api-calls.h
new file mode 100644
index 00000000000000..79a5d4d82a764d
--- /dev/null
+++ b/deps/v8/include/v8-fast-api-calls.h
@@ -0,0 +1,412 @@
+// Copyright 2020 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 file provides additional API on top of the default one for making
+ * API calls, which come from embedder C++ functions. The functions are being
+ * called directly from optimized code, doing all the necessary typechecks
+ * in the compiler itself, instead of on the embedder side. Hence the "fast"
+ * in the name. Example usage might look like:
+ *
+ * \code
+ * void FastMethod(int param, bool another_param);
+ *
+ * v8::FunctionTemplate::New(isolate, SlowCallback, data,
+ * signature, length, constructor_behavior
+ * side_effect_type,
+ * &v8::CFunction::Make(FastMethod));
+ * \endcode
+ *
+ * An example for custom embedder type support might employ a way to wrap/
+ * unwrap various C++ types in JSObject instances, e.g:
+ *
+ * \code
+ *
+ * // Represents the way this type system maps C++ and JS values.
+ * struct WrapperTypeInfo {
+ * // Store e.g. a method to map from exposed C++ types to the already
+ * // created v8::FunctionTemplate's for instantiating them.
+ * };
+ *
+ * // Helper method with a sanity check.
+ * template
+ * inline T* GetInternalField(v8::Local wrapper) {
+ * assert(offset < wrapper->InternalFieldCount());
+ * return reinterpret_cast(
+ * wrapper->GetAlignedPointerFromInternalField(offset));
+ * }
+ *
+ * // Returns the type info from a wrapper JS object.
+ * inline const WrapperTypeInfo* ToWrapperTypeInfo(
+ * v8::Local wrapper) {
+ * return GetInternalField(wrapper);
+ * }
+ *
+ * class CustomEmbedderType {
+ * public:
+ * static constexpr const WrapperTypeInfo* GetWrapperTypeInfo() {
+ * return &custom_type_wrapper_type_info;
+ * }
+ * // Returns the raw C object from a wrapper JS object.
+ * static CustomEmbedderType* Unwrap(v8::Local wrapper) {
+ * return GetInternalField(wrapper);
+ * }
+ * static void FastMethod(CustomEmbedderType* receiver, int param) {
+ * assert(receiver != nullptr);
+ * // Type checks are already done by the optimized code.
+ * // Then call some performance-critical method like:
+ * // receiver->Method(param);
+ * }
+ *
+ * static void SlowMethod(
+ * const v8::FunctionCallbackInfo& info) {
+ * v8::Local instance =
+ * v8::Local::Cast(info.Holder());
+ * CustomEmbedderType* receiver = Unwrap(instance);
+ * // TODO: Do type checks and extract {param}.
+ * FastMethod(receiver, param);
+ * }
+ *
+ * private:
+ * static const WrapperTypeInfo custom_type_wrapper_type_info;
+ * };
+ *
+ * // Support for custom embedder types via specialization of WrapperTraits.
+ * namespace v8 {
+ * template <>
+ * class WrapperTraits {
+ * public:
+ * static const void* GetTypeInfo() {
+ * // We use the already defined machinery for the custom type.
+ * return CustomEmbedderType::GetWrapperTypeInfo();
+ * }
+ * };
+ * } // namespace v8
+ *
+ * // The constants kV8EmbedderWrapperTypeIndex and
+ * // kV8EmbedderWrapperObjectIndex describe the offsets for the type info
+ * // struct (the one returned by WrapperTraits::GetTypeInfo) and the
+ * // native object, when expressed as internal field indices within a
+ * // JSObject. The existance of this helper function assumes that all
+ * // embedder objects have their JSObject-side type info at the same
+ * // offset, but this is not a limitation of the API itself. For a detailed
+ * // use case, see the third example.
+ * static constexpr int kV8EmbedderWrapperTypeIndex = 0;
+ * static constexpr int kV8EmbedderWrapperObjectIndex = 1;
+ *
+ * // The following setup function can be templatized based on
+ * // the {embedder_object} argument.
+ * void SetupCustomEmbedderObject(v8::Isolate* isolate,
+ * v8::Local context,
+ * CustomEmbedderType* embedder_object) {
+ * isolate->set_embedder_wrapper_type_index(
+ * kV8EmbedderWrapperTypeIndex);
+ * isolate->set_embedder_wrapper_object_index(
+ * kV8EmbedderWrapperObjectIndex);
+ *
+ * v8::CFunction c_func =
+ * MakeV8CFunction(CustomEmbedderType::FastMethod);
+ *
+ * Local method_template =
+ * v8::FunctionTemplate::New(
+ * isolate, CustomEmbedderType::SlowMethod, v8::Local(),
+ * v8::Local(), 1, v8::ConstructorBehavior::kAllow,
+ * v8::SideEffectType::kHasSideEffect, &c_func);
+ *
+ * v8::Local object_template =
+ * v8::ObjectTemplate::New(isolate);
+ * object_template->SetInternalFieldCount(
+ * kV8EmbedderWrapperObjectIndex + 1);
+ * object_template->Set(
+ v8::String::NewFromUtf8Literal(isolate, "method"), method_template);
+ *
+ * // Instantiate the wrapper JS object.
+ * v8::Local object =
+ * object_template->NewInstance(context).ToLocalChecked();
+ * object->SetAlignedPointerInInternalField(
+ * kV8EmbedderWrapperObjectIndex,
+ * reinterpret_cast(embedder_object));
+ *
+ * // TODO: Expose {object} where it's necessary.
+ * }
+ * \endcode
+ *
+ * For instance if {object} is exposed via a global "obj" variable,
+ * one could write in JS:
+ * function hot_func() {
+ * obj.method(42);
+ * }
+ * and once {hot_func} gets optimized, CustomEmbedderType::FastMethod
+ * will be called instead of the slow version, with the following arguments:
+ * receiver := the {embedder_object} from above
+ * param := 42
+ *
+ * Currently only void return types are supported.
+ * Currently supported argument types:
+ * - pointer to an embedder type
+ * - bool
+ * - int32_t
+ * - uint32_t
+ * To be supported types:
+ * - int64_t
+ * - uint64_t
+ * - float32_t
+ * - float64_t
+ * - arrays of C types
+ * - arrays of embedder types
+ */
+
+#ifndef INCLUDE_V8_FAST_API_CALLS_H_
+#define INCLUDE_V8_FAST_API_CALLS_H_
+
+#include
+#include
+
+#include "v8config.h" // NOLINT(build/include)
+
+namespace v8 {
+
+class CTypeInfo {
+ public:
+ enum class Type : char {
+ kVoid,
+ kBool,
+ kInt32,
+ kUint32,
+ kInt64,
+ kUint64,
+ kFloat32,
+ kFloat64,
+ kUnwrappedApiObject,
+ };
+
+ enum class ArgFlags : uint8_t {
+ kNone = 0,
+ kIsArrayBit = 1 << 0, // This argument is first in an array of values.
+ };
+
+ static CTypeInfo FromWrapperType(const void* wrapper_type_info,
+ ArgFlags flags = ArgFlags::kNone) {
+ uintptr_t wrapper_type_info_ptr =
+ reinterpret_cast(wrapper_type_info);
+ // Check that the lower kIsWrapperTypeBit bits are 0's.
+ CHECK_EQ(
+ wrapper_type_info_ptr & ~(static_cast(~0)
+ << static_cast(kIsWrapperTypeBit)),
+ 0u);
+ // TODO(mslekova): Refactor the manual bit manipulations to use
+ // PointerWithPayload instead.
+ return CTypeInfo(wrapper_type_info_ptr | static_cast(flags) |
+ kIsWrapperTypeBit);
+ }
+
+ static constexpr CTypeInfo FromCType(Type ctype,
+ ArgFlags flags = ArgFlags::kNone) {
+ // ctype cannot be Type::kUnwrappedApiObject.
+ return CTypeInfo(
+ ((static_cast(ctype) << kTypeOffset) & kTypeMask) |
+ static_cast(flags));
+ }
+
+ const void* GetWrapperInfo() const;
+
+ constexpr Type GetType() const {
+ if (payload_ & kIsWrapperTypeBit) {
+ return Type::kUnwrappedApiObject;
+ }
+ return static_cast((payload_ & kTypeMask) >> kTypeOffset);
+ }
+
+ constexpr bool IsArray() const {
+ return payload_ & static_cast(ArgFlags::kIsArrayBit);
+ }
+
+ private:
+ explicit constexpr CTypeInfo(uintptr_t payload) : payload_(payload) {}
+
+ // That must be the last bit after ArgFlags.
+ static constexpr uintptr_t kIsWrapperTypeBit = 1 << 1;
+ static constexpr uintptr_t kWrapperTypeInfoMask = static_cast(~0)
+ << 2;
+
+ static constexpr unsigned int kTypeOffset = kIsWrapperTypeBit;
+ static constexpr unsigned int kTypeSize = 8 - kTypeOffset;
+ static constexpr uintptr_t kTypeMask =
+ (~(static_cast(~0) << kTypeSize)) << kTypeOffset;
+
+ const uintptr_t payload_;
+};
+
+class CFunctionInfo {
+ public:
+ virtual const CTypeInfo& ReturnInfo() const = 0;
+ virtual unsigned int ArgumentCount() const = 0;
+ virtual const CTypeInfo& ArgumentInfo(unsigned int index) const = 0;
+};
+
+template
+class WrapperTraits {
+ public:
+ static const void* GetTypeInfo() {
+ static_assert(sizeof(T) != sizeof(T),
+ "WrapperTraits must be specialized for this type.");
+ return nullptr;
+ }
+};
+
+namespace internal {
+
+template
+struct GetCType {
+ static_assert(sizeof(T) != sizeof(T), "Unsupported CType");
+};
+
+#define SPECIALIZE_GET_C_TYPE_FOR(ctype, ctypeinfo) \
+ template <> \
+ struct GetCType { \
+ static constexpr CTypeInfo Get() { \
+ return CTypeInfo::FromCType(CTypeInfo::Type::ctypeinfo); \
+ } \
+ };
+
+#define SUPPORTED_C_TYPES(V) \
+ V(void, kVoid) \
+ V(bool, kBool) \
+ V(int32_t, kInt32) \
+ V(uint32_t, kUint32) \
+ V(int64_t, kInt64) \
+ V(uint64_t, kUint64) \
+ V(float, kFloat32) \
+ V(double, kFloat64)
+
+SUPPORTED_C_TYPES(SPECIALIZE_GET_C_TYPE_FOR)
+
+template
+struct EnableIfHasWrapperTypeInfo {};
+
+template
+struct EnableIfHasWrapperTypeInfo::GetTypeInfo(),
+ void())> {
+ typedef void type;
+};
+
+// T* where T is a primitive (array of primitives).
+template
+struct GetCTypePointerImpl {
+ static constexpr CTypeInfo Get() {
+ return CTypeInfo::FromCType(GetCType::Get().GetType(),
+ CTypeInfo::ArgFlags::kIsArrayBit);
+ }
+};
+
+// T* where T is an API object.
+template
+struct GetCTypePointerImpl::type> {
+ static constexpr CTypeInfo Get() {
+ return CTypeInfo::FromWrapperType(WrapperTraits::GetTypeInfo());
+ }
+};
+
+// T** where T is a primitive. Not allowed.
+template
+struct GetCTypePointerPointerImpl {
+ static_assert(sizeof(T**) != sizeof(T**), "Unsupported type");
+};
+
+// T** where T is an API object (array of API objects).
+template
+struct GetCTypePointerPointerImpl<
+ T, typename EnableIfHasWrapperTypeInfo::type> {
+ static constexpr CTypeInfo Get() {
+ return CTypeInfo::FromWrapperType(WrapperTraits::GetTypeInfo(),
+ CTypeInfo::ArgFlags::kIsArrayBit);
+ }
+};
+
+template
+struct GetCType : public GetCTypePointerPointerImpl {};
+
+template
+struct GetCType : public GetCTypePointerImpl {};
+
+template
+class CFunctionInfoImpl : public CFunctionInfo {
+ public:
+ CFunctionInfoImpl()
+ : return_info_(internal::GetCType::Get()),
+ arg_count_(sizeof...(Args)),
+ arg_info_{internal::GetCType::Get()...} {
+ static_assert(
+ internal::GetCType::Get().GetType() == CTypeInfo::Type::kVoid,
+ "Only void return types are currently supported.");
+ }
+
+ const CTypeInfo& ReturnInfo() const override { return return_info_; }
+ unsigned int ArgumentCount() const override { return arg_count_; }
+ const CTypeInfo& ArgumentInfo(unsigned int index) const override {
+ CHECK_LT(index, ArgumentCount());
+ return arg_info_[index];
+ }
+
+ private:
+ CTypeInfo return_info_;
+ const unsigned int arg_count_;
+ CTypeInfo arg_info_[sizeof...(Args)];
+};
+
+} // namespace internal
+
+class V8_EXPORT CFunction {
+ public:
+ constexpr CFunction() : address_(nullptr), type_info_(nullptr) {}
+
+ const CTypeInfo& ReturnInfo() const { return type_info_->ReturnInfo(); }
+
+ const CTypeInfo& ArgumentInfo(unsigned int index) const {
+ return type_info_->ArgumentInfo(index);
+ }
+
+ unsigned int ArgumentCount() const { return type_info_->ArgumentCount(); }
+
+ const void* GetAddress() const { return address_; }
+ const CFunctionInfo* GetTypeInfo() const { return type_info_; }
+
+ template
+ static CFunction Make(F* func) {
+ return ArgUnwrap::Make(func);
+ }
+
+ private:
+ const void* address_;
+ const CFunctionInfo* type_info_;
+
+ CFunction(const void* address, const CFunctionInfo* type_info);
+
+ template
+ static CFunctionInfo* GetCFunctionInfo() {
+ static internal::CFunctionInfoImpl instance;
+ return &instance;
+ }
+
+ template
+ class ArgUnwrap {
+ static_assert(sizeof(F) != sizeof(F),
+ "CFunction must be created from a function pointer.");
+ };
+
+ template
+ class ArgUnwrap {
+ public:
+ static CFunction Make(R (*func)(Args...)) {
+ return CFunction(reinterpret_cast(func),
+ GetCFunctionInfo());
+ }
+ };
+};
+
+} // namespace v8
+
+#endif // INCLUDE_V8_FAST_API_CALLS_H_
diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h
index 99333cb7319e62..01274625c1f476 100644
--- a/deps/v8/include/v8-inspector.h
+++ b/deps/v8/include/v8-inspector.h
@@ -145,9 +145,6 @@ class V8_EXPORT V8InspectorSession {
virtual void breakProgram(StringView breakReason,
StringView breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
-
- // NOTE: setTerminateOnResume is not implemented on the base version of
- // Node.js v14.0.0 / V8 8.1.
virtual void resume(bool setTerminateOnResume = false) = 0;
virtual void stepOver() = 0;
virtual std::vector>
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index f21a0b8dd0fd69..64f184866537b5 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 8
-#define V8_MINOR_VERSION 1
-#define V8_BUILD_NUMBER 307
-#define V8_PATCH_LEVEL 31
+#define V8_MINOR_VERSION 3
+#define V8_BUILD_NUMBER 110
+#define V8_PATCH_LEVEL 9
// 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 d09055e15d2fbd..406c47383b714d 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -120,6 +120,8 @@ class EscapableHandleScope;
template class ReturnValue;
namespace internal {
+enum class ArgumentsType;
+template
class Arguments;
class DeferredHandles;
class Heap;
@@ -149,11 +151,6 @@ class ConsoleCallArguments;
// --- Handles ---
-#define TYPE_CHECK(T, S) \
- while (false) { \
- *(static_cast(0)) = static_cast(0); \
- }
-
/**
* An object reference managed by the v8 garbage collector.
*
@@ -197,7 +194,7 @@ class Local {
* handles. For example, converting from a Local to a
* Local.
*/
- TYPE_CHECK(T, S);
+ static_assert(std::is_base_of::value, "type check");
}
/**
@@ -363,7 +360,7 @@ class MaybeLocal {
template
V8_INLINE MaybeLocal(Local that)
: val_(reinterpret_cast(*that)) {
- TYPE_CHECK(T, S);
+ static_assert(std::is_base_of::value, "type check");
}
V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
@@ -532,11 +529,16 @@ template class PersistentBase {
}
/**
- * Install a finalization callback on this object.
- * NOTE: There is no guarantee as to *when* or even *if* the callback is
- * invoked. The invocation is performed solely on a best effort basis.
- * As always, GC-based finalization should *not* be relied upon for any
- * critical form of resource management!
+ * Install a finalization callback on this object.
+ * NOTE: There is no guarantee as to *when* or even *if* the callback is
+ * invoked. The invocation is performed solely on a best effort basis.
+ * As always, GC-based finalization should *not* be relied upon for any
+ * critical form of resource management!
+ *
+ * The callback is supposed to reset the handle. 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::SetSecondPassCallback.
*/
template
V8_INLINE void SetWeak(P* parameter,
@@ -618,11 +620,8 @@ class NonCopyablePersistentTraits {
template
V8_INLINE static void Copy(const Persistent& source,
NonCopyablePersistent* dest) {
- Uncompilable |