diff --git a/.eslintrc.js b/.eslintrc.js
index 0a6b96877ec0c2..8acba223d986eb 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -324,5 +324,6 @@ module.exports = {
TextEncoder: 'readable',
TextDecoder: 'readable',
queueMicrotask: 'readable',
+ globalThis: 'readable',
},
};
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index d319d377249b8b..428bbf678a34c3 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -3,6 +3,6 @@ contact_links:
- name: ⁉️ Need help with Node.js?
url: https://github.com/nodejs/help
about: Please file an issue in our help repo.
- - name: 🌐 Found a problem with nodejs.org?
+ - name: 🌐 Found a problem with nodejs.org beyond the API reference docs?
url: https://github.com/nodejs/nodejs.org/issues/new/choose
about: Please file an issue in the Node.js website repo.
diff --git a/.travis.yml b/.travis.yml
index b8811073331932..e1069317ecc2c5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -88,3 +88,4 @@ jobs:
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
allow_failures: # TODO (cclauss): remove this when dependencies are clean
- name: "Find syntax errors in our Python dependencies"
+ - name: "First commit message adheres to guidelines at https://goo.gl/p2fr5Q"
diff --git a/BUILDING.md b/BUILDING.md
index b44604ecf07734..d188aaff5a3a27 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -23,7 +23,7 @@ file a new issue.
* [Unix and macOS](#unix-and-macos)
* [Unix prerequisites](#unix-prerequisites)
* [macOS prerequisites](#macos-prerequisites)
- * [Building Node.js](#building-nodejs)
+ * [Building Node.js](#building-nodejs-1)
* [Running Tests](#running-tests)
* [Running Coverage](#running-coverage)
* [Building the documentation](#building-the-documentation)
@@ -31,7 +31,7 @@ file a new issue.
* [Windows](#windows)
* [Prerequisites](#prerequisites)
* [Option 1: Manual install](#option-1-manual-install)
- * [Option 1: Automated install with Boxstarter](#option-1-automated-install-with-boxstarter)
+ * [Option 2: Automated install with Boxstarter](#option-2-automated-install-with-boxstarter)
* [Building Node.js](#building-nodejs-1)
* [Android/Android-based devices (e.g. Firefox OS)](#androidandroid-based-devices-eg-firefox-os)
* [`Intl` (ECMA-402) support](#intl-ecma-402-support)
@@ -67,30 +67,25 @@ There are three support tiers:
* **Tier 1**: These platforms represent the majority of Node.js users. The
Node.js Build Working Group maintains infrastructure for full test coverage.
- All commits to the Node.js repository are tested on these platforms. Test
- failures on tier 1 platforms will block releases.
+ Test failures on tier 1 platforms will block releases.
* **Tier 2**: These platforms represent smaller segments of the Node.js user
base. The Node.js Build Working Group maintains infrastructure for full test
- coverage. All commits to the Node.js repository are tested on these platforms.
- Test failures on tier 2 platforms will block releases. Delays in release of
- binaries for these platforms are acceptable where necessary due to
- infrastructure concerns.
+ coverage. Test failures on tier 2 platforms will block releases.
+ Infrastructure issues may delay the release of binaries for these platforms.
* **Experimental**: May not compile or test suite may not pass. The core team
does not create releases for these platforms. Test failures on experimental
platforms do not block releases. Contributions to improve support for these
platforms are welcome.
Platforms may move between tiers between major release lines. The table below
-will be updated to reflect those changes.
+will reflect those changes.
### Platform list
-Compiling and running Node.js is supported for a limited set of operating
-systems, architectures and libc versions. The table below lists the
-combinations that the core team has committed to supporting and the nature of
-that support as per the support tiers above. A list of
-[supported compile toolchains](#supported-toolchains) is also supplied for
-tier 1 platforms.
+Node.js compilation/execution support depends on operating system, architecture,
+and libc version. The table below lists the support tier for each supported
+combination. A list of [supported compile toolchains](#supported-toolchains) is
+also supplied for tier 1 platforms.
**For production applications, run Node.js on supported platforms only.**
@@ -116,26 +111,26 @@ platforms. This is true regardless of entries in the table below.
| AIX | ppc64be >=power7 | >= 7.2 TL02 | Tier 2 | |
| FreeBSD | x64 | >= 11 | Experimental | Downgraded as of Node.js 12 [7](#fn7) |
-1: GCC 6 is not provided on the base platform, users will
+1: GCC 6 is not provided on the base platform. Users will
need the
[Toolchain test builds PPA](https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test?field.series_filter=xenial)
or similar to source a newer compiler.
-2: GCC 6 is not provided on the base platform, users will
+2: GCC 6 is not provided on the base platform. Users will
need the
[devtoolset-6](https://www.softwarecollections.org/en/scls/rhscl/devtoolset-6/)
or later to source a newer compiler.
-3: Older kernel versions may work for ARM64, however the
+3: Older kernel versions may work for ARM64. However the
Node.js test infrastructure only tests >= 4.5.
4: On Windows, running Node.js in Windows terminal emulators
like `mintty` requires the usage of [winpty](https://github.com/rprichard/winpty)
- for the tty channels to work correctly (e.g. `winpty node.exe script.js`).
+ for the tty channels to work (e.g. `winpty node.exe script.js`).
In "Git bash" if you call the node shell alias (`node` without the `.exe`
extension), `winpty` is used automatically.
-5: The Windows Subsystem for Linux (WSL) is not directly
+5: The Windows Subsystem for Linux (WSL) is not
supported, but the GNU/Linux build process and binaries should work. The
community will only address issues that reproduce on native GNU/Linux
systems. Issues that only reproduce on WSL should be reported in the
@@ -145,11 +140,11 @@ platforms. This is true regardless of entries in the table below.
6: Running Node.js on x86 Windows should work and binaries
are provided. However, tests in our infrastructure only run on WoW64.
-Furthermore, compiling on x86 Windows is currently considered Experimental and
+Furthermore, compiling on x86 Windows is Experimental and
may not be possible.
7: The default FreeBSD 12.0 compiler is Clang 6.0.1, but
-FreeBSD 12.1 upgrades to 8.0.1. Other Clang/LLVM versions are provided
+FreeBSD 12.1 upgrades to 8.0.1. Other Clang/LLVM versions are available
via the system's package manager, including Clang 9.0.
### Supported toolchains
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec16a2f3d8cd5c..f02bdaae23489d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,7 +28,8 @@ release.
-12.14.1
+12.15.0
+12.14.1 12.14.0 12.13.1 12.13.0
diff --git a/CPP_STYLE_GUIDE.md b/CPP_STYLE_GUIDE.md
index f29c8df3210caa..f3dcd4e647b04e 100644
--- a/CPP_STYLE_GUIDE.md
+++ b/CPP_STYLE_GUIDE.md
@@ -14,9 +14,9 @@ codebase not related to stylistic issues.
* [Align function arguments vertically](#align-function-arguments-vertically)
* [Initialization lists](#initialization-lists)
* [CamelCase for methods, functions, and classes](#camelcase-for-methods-functions-and-classes)
- * [snake\_case for local variables and parameters](#snake_case-for-local-variables-and-parameters)
- * [snake\_case\_ for private class fields](#snake_case_-for-private-class-fields)
- * [snake\_case for C-like structs](#snake_case-for-c-like-structs)
+ * [`snake_case` for local variables and parameters](#snake_case-for-local-variables-and-parameters)
+ * [`snake_case_` for private class fields](#snake_case_-for-private-class-fields)
+ * [`snake_case` for C-like structs](#snake_case-for-c-like-structs)
* [Space after `template`](#space-after-template)
* [Memory Management](#memory-management)
* [Memory allocation](#memory-allocation)
@@ -155,7 +155,7 @@ class FooBar {
};
```
-### snake\_case for local variables and parameters
+### `snake_case` for local variables and parameters
```c++
int FunctionThatDoesSomething(const char* important_string) {
@@ -163,7 +163,7 @@ int FunctionThatDoesSomething(const char* important_string) {
}
```
-### snake\_case\_ for private class fields
+### `snake_case_` for private class fields
```c++
class Foo {
@@ -172,7 +172,8 @@ class Foo {
};
```
-### snake\_case for C-like structs
+### `snake_case` for C-like structs
+
For plain C-like structs snake_case can be used.
```c++
diff --git a/LICENSE b/LICENSE
index f57c3dc0c37194..db59472ba13151 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1526,3 +1526,28 @@ The externally maintained libraries used by Node.js are:
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
+
+- uvwasi, located at deps/uvwasi, is licensed as follows:
+ """
+ MIT License
+
+ Copyright (c) 2019 Colin Ihrig and Contributors
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ """
diff --git a/Makefile b/Makefile
index 56f53582d1f494..05eaa73abbe0c6 100644
--- a/Makefile
+++ b/Makefile
@@ -842,6 +842,7 @@ endif
endif
endif
endif
+endif
ifeq ($(DESTCPU),x64)
ARCH=x64
else
@@ -871,7 +872,6 @@ endif
endif
endif
endif
-endif
# node and v8 use different arch names (e.g. node 'x86' vs v8 'ia32').
# pass the proper v8 arch name to $V8_ARCH based on user-specified $DESTCPU.
diff --git a/SECURITY.md b/SECURITY.md
index 7e984b7ba36872..3196055ccb78e5 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -23,8 +23,8 @@ the HackerOne platform. See for further details.
## Reporting a Bug in a third party module
Security bugs in third party modules should be reported to their respective
-maintainers and should also be coordinated through the Node Ecosystem Security
-Team via [HackerOne](https://hackerone.com/nodejs-ecosystem).
+maintainers and should also be coordinated through the Node.js Ecosystem
+Security Team via [HackerOne](https://hackerone.com/nodejs-ecosystem).
Details regarding this process can be found in the
[Security Working Group repository](https://github.com/nodejs/security-wg/blob/master/processes/third_party_vuln_process.md).
diff --git a/benchmark/README.md b/benchmark/README.md
index 45256670fdd2aa..c5fdad093471b5 100644
--- a/benchmark/README.md
+++ b/benchmark/README.md
@@ -5,7 +5,7 @@ of different Node.js implementations and different ways of
writing JavaScript run by the built-in JavaScript engine.
For a detailed guide on how to write and run benchmarks in this
-directory, see [the guide on benchmarks](../doc/guides/writing-and-running-benchmarks.md).
+directory, see [the guide on benchmarks](writing-and-running-benchmarks.md).
## Table of Contents
@@ -74,21 +74,21 @@ The common.js module is used by benchmarks for consistency across repeated
tasks. It has a number of helpful functions and properties to help with
writing benchmarks.
-### createBenchmark(fn, configs\[, options\])
+### `createBenchmark(fn, configs[, options])`
-See [the guide on writing benchmarks](../doc/guides/writing-and-running-benchmarks.md#basics-of-a-benchmark).
+See [the guide on writing benchmarks](writing-and-running-benchmarks.md#basics-of-a-benchmark).
-### default\_http\_benchmarker
+### `default_http_benchmarker`
The default benchmarker used to run HTTP benchmarks.
-See [the guide on writing HTTP benchmarks](../doc/guides/writing-and-running-benchmarks.md#creating-an-http-benchmark).
+See [the guide on writing HTTP benchmarks](writing-and-running-benchmarks.md#creating-an-http-benchmark).
-### PORT
+### `PORT`
The default port used to run HTTP benchmarks.
-See [the guide on writing HTTP benchmarks](../doc/guides/writing-and-running-benchmarks.md#creating-an-http-benchmark).
+See [the guide on writing HTTP benchmarks](writing-and-running-benchmarks.md#creating-an-http-benchmark).
-### sendResult(data)
+### `sendResult(data)`
Used in special benchmarks that can't use `createBenchmark` and the object
it returns to accomplish what they need. This function reports timing
diff --git a/benchmark/_cli.js b/benchmark/_cli.js
index 8b9f22d0fb4b57..771cc72bff1964 100644
--- a/benchmark/_cli.js
+++ b/benchmark/_cli.js
@@ -34,7 +34,7 @@ function CLI(usage, settings) {
if (arg === '--') {
// Only items can follow --
mode = 'item';
- } else if (['both', 'option'].includes(mode) && arg[0] === '-') {
+ } else if ('both' === mode && arg[0] === '-') {
// Optional arguments declaration
if (arg[1] === '-') {
@@ -82,13 +82,12 @@ CLI.prototype.abort = function(msg) {
CLI.prototype.benchmarks = function() {
const paths = [];
- const filter = this.optional.filter || false;
for (const category of this.items) {
if (benchmarks[category] === undefined)
continue;
for (const scripts of benchmarks[category]) {
- if (filter && scripts.lastIndexOf(filter) === -1) continue;
+ if (this.shouldSkip(scripts)) continue;
paths.push(path.join(category, scripts));
}
@@ -96,3 +95,23 @@ CLI.prototype.benchmarks = function() {
return paths;
};
+
+CLI.prototype.shouldSkip = function(scripts) {
+ const filters = this.optional.filter || [];
+ const excludes = this.optional.exclude || [];
+ let skip = filters.length > 0;
+
+ for (const filter of filters) {
+ if (scripts.lastIndexOf(filter) !== -1) {
+ skip = false;
+ }
+ }
+
+ for (const exclude of excludes) {
+ if (scripts.lastIndexOf(exclude) !== -1) {
+ skip = true;
+ }
+ }
+
+ return skip;
+};
diff --git a/benchmark/_http-benchmarkers.js b/benchmark/_http-benchmarkers.js
index a4d623003947eb..7dd06be2655744 100644
--- a/benchmark/_http-benchmarkers.js
+++ b/benchmark/_http-benchmarkers.js
@@ -5,7 +5,7 @@ const path = require('path');
const fs = require('fs');
const requirementsURL =
- 'https://github.com/nodejs/node/blob/master/doc/guides/writing-and-running-benchmarks.md#http-benchmark-requirements';
+ 'https://github.com/nodejs/node/blob/master/benchmark/writing-and-running-benchmarks.md#http-benchmark-requirements';
// The port used by servers and wrk
exports.PORT = Number(process.env.PORT) || 12346;
diff --git a/benchmark/async_hooks/http-server.js b/benchmark/async_hooks/http-server.js
new file mode 100644
index 00000000000000..493500fd1f2d66
--- /dev/null
+++ b/benchmark/async_hooks/http-server.js
@@ -0,0 +1,40 @@
+'use strict';
+const common = require('../common.js');
+
+const bench = common.createBenchmark(main, {
+ asyncHooks: ['init', 'before', 'after', 'all', 'disabled', 'none'],
+ connections: [50, 500]
+});
+
+function main({ asyncHooks, connections }) {
+ if (asyncHooks !== 'none') {
+ let hooks = {
+ init() {},
+ before() {},
+ after() {},
+ destroy() {},
+ promiseResolve() {}
+ };
+ if (asyncHooks !== 'all' || asyncHooks !== 'disabled') {
+ hooks = {
+ [asyncHooks]: () => {}
+ };
+ }
+ const hook = require('async_hooks').createHook(hooks);
+ if (asyncHooks !== 'disabled') {
+ hook.enable();
+ }
+ }
+ const server = require('../fixtures/simple-http-server.js')
+ .listen(common.PORT)
+ .on('listening', () => {
+ const path = '/buffer/4/4/normal/1';
+
+ bench.http({
+ connections,
+ path,
+ }, () => {
+ server.close();
+ });
+ });
+}
diff --git a/benchmark/buffers/buffer-bytelength.js b/benchmark/buffers/buffer-bytelength.js
index 3246a42d96b34c..1b324a49f89de8 100644
--- a/benchmark/buffers/buffer-bytelength.js
+++ b/benchmark/buffers/buffer-bytelength.js
@@ -16,8 +16,8 @@ const chars = [
];
function main({ n, len, encoding }) {
- var strings = [];
- var results = [ len * 16 ];
+ let strings = [];
+ let results = [ len * 16 ];
if (encoding === 'buffer') {
strings = [ Buffer.alloc(len * 16, 'a') ];
} else {
diff --git a/benchmark/buffers/buffer-compare-instance-method.js b/benchmark/buffers/buffer-compare-instance-method.js
index 284001c236d99d..eb18fa518037f4 100644
--- a/benchmark/buffers/buffer-compare-instance-method.js
+++ b/benchmark/buffers/buffer-compare-instance-method.js
@@ -12,7 +12,6 @@ function main({ n, size, args }) {
const b1 = Buffer.alloc(size, 'a');
const b0Len = b0.length;
const b1Len = b1.length;
- var i;
b1[size - 1] = 'b'.charCodeAt(0);
@@ -20,7 +19,7 @@ function main({ n, size, args }) {
case 2:
b0.compare(b1, 0);
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
b0.compare(b1, 0);
}
bench.end(n);
@@ -28,7 +27,7 @@ function main({ n, size, args }) {
case 3:
b0.compare(b1, 0, b1Len);
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
b0.compare(b1, 0, b1Len);
}
bench.end(n);
@@ -36,7 +35,7 @@ function main({ n, size, args }) {
case 4:
b0.compare(b1, 0, b1Len, 0);
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
b0.compare(b1, 0, b1Len, 0);
}
bench.end(n);
@@ -44,7 +43,7 @@ function main({ n, size, args }) {
case 5:
b0.compare(b1, 0, b1Len, 0, b0Len);
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
b0.compare(b1, 0, b1Len, 0, b0Len);
}
bench.end(n);
@@ -52,7 +51,7 @@ function main({ n, size, args }) {
default:
b0.compare(b1);
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
b0.compare(b1);
}
bench.end(n);
diff --git a/benchmark/buffers/buffer-hex.js b/benchmark/buffers/buffer-hex.js
index 1b49ca745381da..33d2b44d6a5950 100644
--- a/benchmark/buffers/buffer-hex.js
+++ b/benchmark/buffers/buffer-hex.js
@@ -9,16 +9,15 @@ const bench = common.createBenchmark(main, {
function main({ len, n }) {
const buf = Buffer.alloc(len);
- var i;
- for (i = 0; i < buf.length; i++)
+ for (let i = 0; i < buf.length; i++)
buf[i] = i & 0xff;
const hex = buf.toString('hex');
bench.start();
- for (i = 0; i < n; i += 1)
+ for (let i = 0; i < n; i += 1)
Buffer.from(hex, 'hex');
bench.end(n);
diff --git a/benchmark/buffers/buffer-indexof.js b/benchmark/buffers/buffer-indexof.js
index e635da2351c4a7..4c0993a1ef0ef9 100644
--- a/benchmark/buffers/buffer-indexof.js
+++ b/benchmark/buffers/buffer-indexof.js
@@ -25,7 +25,7 @@ const bench = common.createBenchmark(main, {
});
function main({ n, search, encoding, type }) {
- var aliceBuffer = fs.readFileSync(
+ let aliceBuffer = fs.readFileSync(
path.resolve(__dirname, '../fixtures/alice.html')
);
diff --git a/benchmark/buffers/buffer-iterate.js b/benchmark/buffers/buffer-iterate.js
index e81ce2b3035d90..de002108a95d65 100644
--- a/benchmark/buffers/buffer-iterate.js
+++ b/benchmark/buffers/buffer-iterate.js
@@ -29,15 +29,15 @@ function main({ size, type, method, n }) {
}
function benchFor(buffer, n) {
- for (var k = 0; k < n; k++) {
- for (var i = 0; i < buffer.length; i++) {
+ for (let k = 0; k < n; k++) {
+ for (let i = 0; i < buffer.length; i++) {
assert(buffer[i] === 0);
}
}
}
function benchForOf(buffer, n) {
- for (var k = 0; k < n; k++) {
+ for (let k = 0; k < n; k++) {
for (const b of buffer) {
assert(b === 0);
}
@@ -45,7 +45,7 @@ function benchForOf(buffer, n) {
}
function benchIterator(buffer, n) {
- for (var k = 0; k < n; k++) {
+ for (let k = 0; k < n; k++) {
const iter = buffer[Symbol.iterator]();
let cur = iter.next();
diff --git a/benchmark/buffers/buffer-swap.js b/benchmark/buffers/buffer-swap.js
index d22bf2fd5504ea..a33bac4ae3ed78 100644
--- a/benchmark/buffers/buffer-swap.js
+++ b/benchmark/buffers/buffer-swap.js
@@ -36,7 +36,7 @@ Buffer.prototype.htons = function htons() {
Buffer.prototype.htonl = function htonl() {
if (this.length % 4 !== 0)
throw new RangeError();
- for (var i = 0; i < this.length; i += 4) {
+ for (let i = 0; i < this.length; i += 4) {
swap(this, i, i + 3);
swap(this, i + 1, i + 2);
}
@@ -66,7 +66,7 @@ function createBuffer(len, aligned) {
function genMethod(method) {
const fnString = `
return function ${method}(n, buf) {
- for (var i = 0; i <= n; i++)
+ for (let i = 0; i <= n; i++)
buf.${method}();
}`;
return (new Function(fnString))();
diff --git a/benchmark/buffers/buffer-tostring.js b/benchmark/buffers/buffer-tostring.js
index 88543d8fd3af5a..98d6ab3fa08311 100644
--- a/benchmark/buffers/buffer-tostring.js
+++ b/benchmark/buffers/buffer-tostring.js
@@ -15,29 +15,28 @@ function main({ encoding, args, len, n }) {
if (encoding.length === 0)
encoding = undefined;
- var i;
switch (args) {
case 1:
bench.start();
- for (i = 0; i < n; i += 1)
+ for (let i = 0; i < n; i += 1)
buf.toString(encoding);
bench.end(n);
break;
case 2:
bench.start();
- for (i = 0; i < n; i += 1)
+ for (let i = 0; i < n; i += 1)
buf.toString(encoding, 0);
bench.end(n);
break;
case 3:
bench.start();
- for (i = 0; i < n; i += 1)
+ for (let i = 0; i < n; i += 1)
buf.toString(encoding, 0, len);
bench.end(n);
break;
default:
bench.start();
- for (i = 0; i < n; i += 1)
+ for (let i = 0; i < n; i += 1)
buf.toString();
bench.end(n);
break;
diff --git a/benchmark/buffers/buffer-write-string.js b/benchmark/buffers/buffer-write-string.js
index b30edcf8867adf..cd24d379728cda 100644
--- a/benchmark/buffers/buffer-write-string.js
+++ b/benchmark/buffers/buffer-write-string.js
@@ -15,21 +15,19 @@ function main({ len, n, encoding, args }) {
let start = 0;
const buf = Buffer.allocUnsafe(len);
- var i;
-
switch (args) {
case 'offset':
string = 'a'.repeat(Math.floor(len / 2));
start = len - string.length;
if (encoding) {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string, start, encoding);
}
bench.end(n);
} else {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string, start);
}
bench.end(n);
@@ -39,13 +37,13 @@ function main({ len, n, encoding, args }) {
string = 'a'.repeat(len);
if (encoding) {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string, 0, buf.length, encoding);
}
bench.end(n);
} else {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string, 0, buf.length);
}
bench.end(n);
@@ -55,13 +53,13 @@ function main({ len, n, encoding, args }) {
string = 'a'.repeat(len);
if (encoding) {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string, encoding);
}
bench.end(n);
} else {
bench.start();
- for (i = 0; i < n; ++i) {
+ for (let i = 0; i < n; ++i) {
buf.write(string);
}
bench.end(n);
diff --git a/benchmark/child_process/child-process-exec-stdout.js b/benchmark/child_process/child-process-exec-stdout.js
index a1dc4aa04c72a9..f750e2cf3e68f2 100644
--- a/benchmark/child_process/child-process-exec-stdout.js
+++ b/benchmark/child_process/child-process-exec-stdout.js
@@ -19,7 +19,7 @@ function childProcessExecStdout({ dur, len }) {
const cmd = `yes "${'.'.repeat(len)}"`;
const child = exec(cmd, { 'stdio': ['ignore', 'pipe', 'ignore'] });
- var bytes = 0;
+ let bytes = 0;
child.stdout.on('data', (msg) => {
bytes += msg.length;
});
diff --git a/benchmark/child_process/child-process-read-ipc.js b/benchmark/child_process/child-process-read-ipc.js
index a9e9cdf7fd7914..827f75b1e54bd1 100644
--- a/benchmark/child_process/child-process-read-ipc.js
+++ b/benchmark/child_process/child-process-read-ipc.js
@@ -26,7 +26,7 @@ if (process.argv[2] === 'child') {
const child = spawn(process.argv[0],
[process.argv[1], 'child', len], options);
- var bytes = 0;
+ let bytes = 0;
child.on('message', (msg) => { bytes += msg.length; });
setTimeout(() => {
diff --git a/benchmark/child_process/child-process-read.js b/benchmark/child_process/child-process-read.js
index 3c0144116f589f..01e9846be22b56 100644
--- a/benchmark/child_process/child-process-read.js
+++ b/benchmark/child_process/child-process-read.js
@@ -24,7 +24,7 @@ function main({ dur, len }) {
const options = { 'stdio': ['ignore', 'pipe', 'ignore'] };
const child = child_process.spawn('yes', [msg], options);
- var bytes = 0;
+ let bytes = 0;
child.stdout.on('data', (msg) => {
bytes += msg.length;
});
diff --git a/benchmark/cluster/echo.js b/benchmark/cluster/echo.js
index 73c5971cd41eb2..9def87cf8b0e98 100644
--- a/benchmark/cluster/echo.js
+++ b/benchmark/cluster/echo.js
@@ -7,15 +7,24 @@ if (cluster.isMaster) {
workers: [1],
payload: ['string', 'object'],
sendsPerBroadcast: [1, 10],
+ serialization: ['json', 'advanced'],
n: [1e5]
});
- function main({ n, workers, sendsPerBroadcast, payload }) {
+ function main({
+ n,
+ workers,
+ sendsPerBroadcast,
+ payload,
+ serialization
+ }) {
const expectedPerBroadcast = sendsPerBroadcast * workers;
- var readies = 0;
- var broadcasts = 0;
- var msgCount = 0;
- var data;
+ let readies = 0;
+ let broadcasts = 0;
+ let msgCount = 0;
+ let data;
+
+ cluster.settings.serialization = serialization;
switch (payload) {
case 'string':
@@ -28,7 +37,7 @@ if (cluster.isMaster) {
throw new Error('Unsupported payload type');
}
- for (var i = 0; i < workers; ++i)
+ for (let i = 0; i < workers; ++i)
cluster.fork().on('online', onOnline).on('message', onMessage);
function onOnline() {
@@ -39,16 +48,15 @@ if (cluster.isMaster) {
}
function broadcast() {
- var id;
if (broadcasts++ === n) {
bench.end(n);
- for (id in cluster.workers)
+ for (const id in cluster.workers)
cluster.workers[id].disconnect();
return;
}
- for (id in cluster.workers) {
+ for (const id in cluster.workers) {
const worker = cluster.workers[id];
- for (var i = 0; i < sendsPerBroadcast; ++i)
+ for (let i = 0; i < sendsPerBroadcast; ++i)
worker.send(data);
}
}
diff --git a/benchmark/compare.js b/benchmark/compare.js
index bd7c4a95cbb617..53f82bb4b9f1b9 100644
--- a/benchmark/compare.js
+++ b/benchmark/compare.js
@@ -18,10 +18,13 @@ const cli = CLI(`usage: ./node compare.js [options] [--] ...
--new ./new-node-binary new node binary (required)
--old ./old-node-binary old node binary (required)
--runs 30 number of samples
- --filter pattern string to filter benchmark scripts
+ --filter pattern includes only benchmark scripts matching
+ (can be repeated)
+ --exclude pattern excludes scripts matching (can be
+ repeated)
--set variable=value set benchmark variable (can be repeated)
--no-progress don't show benchmark progress indicator
-`, { arrayArgs: ['set'], boolArgs: ['no-progress'] });
+`, { arrayArgs: ['set', 'filter', 'exclude'], boolArgs: ['no-progress'] });
if (!cli.optional.new || !cli.optional.old) {
cli.abort(cli.usage);
diff --git a/benchmark/crypto/aes-gcm-throughput.js b/benchmark/crypto/aes-gcm-throughput.js
index cd8f29c8c7d7b2..b1b08c481700ea 100644
--- a/benchmark/crypto/aes-gcm-throughput.js
+++ b/benchmark/crypto/aes-gcm-throughput.js
@@ -25,7 +25,7 @@ function AEAD_Bench(cipher, message, associate_data, key, iv, n, len) {
const bits = written * 8;
const mbits = bits / (1024 * 1024);
- for (var i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
const alice = crypto.createCipheriv(cipher, key, iv);
alice.setAAD(associate_data);
const enc = alice.update(message);
diff --git a/benchmark/crypto/cipher-stream.js b/benchmark/crypto/cipher-stream.js
index f426a32769d0dd..4bb1695e2d20cc 100644
--- a/benchmark/crypto/cipher-stream.js
+++ b/benchmark/crypto/cipher-stream.js
@@ -38,8 +38,8 @@ function main({ api, cipher, type, len, writes }) {
const alice_cipher = crypto.createCipher(cipher, alice_secret);
const bob_cipher = crypto.createDecipher(cipher, bob_secret);
- var message;
- var encoding;
+ let message;
+ let encoding;
switch (type) {
case 'asc':
message = 'a'.repeat(len);
@@ -65,7 +65,7 @@ function main({ api, cipher, type, len, writes }) {
}
function streamWrite(alice, bob, message, encoding, writes) {
- var written = 0;
+ let written = 0;
bob.on('data', (c) => {
written += c.length;
});
@@ -86,9 +86,9 @@ function streamWrite(alice, bob, message, encoding, writes) {
}
function legacyWrite(alice, bob, message, encoding, writes) {
- var written = 0;
- var enc, dec;
- for (var i = 0; i < writes; i++) {
+ let written = 0;
+ let enc, dec;
+ for (let i = 0; i < writes; i++) {
enc = alice.update(message, encoding);
dec = bob.update(enc);
written += dec.length;
diff --git a/benchmark/crypto/get-ciphers.js b/benchmark/crypto/get-ciphers.js
index 5bbe0915311484..1bf910a6a80ba3 100644
--- a/benchmark/crypto/get-ciphers.js
+++ b/benchmark/crypto/get-ciphers.js
@@ -9,7 +9,7 @@ const bench = common.createBenchmark(main, {
function main({ n, v }) {
const method = require(v).getCiphers;
- var i = 0;
+ let i = 0;
// First call to getCiphers will dominate the results
if (n > 1) {
for (; i < n; i++)
diff --git a/benchmark/crypto/hash-stream-creation.js b/benchmark/crypto/hash-stream-creation.js
index 0a98eb1471c9d4..c21eb6eaaaed99 100644
--- a/benchmark/crypto/hash-stream-creation.js
+++ b/benchmark/crypto/hash-stream-creation.js
@@ -20,8 +20,8 @@ function main({ api, type, len, out, writes, algo }) {
api = 'legacy';
}
- var message;
- var encoding;
+ let message;
+ let encoding;
switch (type) {
case 'asc':
message = 'a'.repeat(len);
@@ -52,7 +52,7 @@ function legacyWrite(algo, message, encoding, writes, len, outEnc) {
while (writes-- > 0) {
const h = crypto.createHash(algo);
h.update(message, encoding);
- var res = h.digest(outEnc);
+ let res = h.digest(outEnc);
// Include buffer creation costs for older versions
if (outEnc === 'buffer' && typeof res === 'string')
diff --git a/benchmark/crypto/hash-stream-throughput.js b/benchmark/crypto/hash-stream-throughput.js
index 52be3d4caf8501..b86d70604616b5 100644
--- a/benchmark/crypto/hash-stream-throughput.js
+++ b/benchmark/crypto/hash-stream-throughput.js
@@ -19,8 +19,8 @@ function main({ api, type, len, algo, writes }) {
api = 'legacy';
}
- var message;
- var encoding;
+ let message;
+ let encoding;
switch (type) {
case 'asc':
message = 'a'.repeat(len);
diff --git a/benchmark/crypto/rsa-encrypt-decrypt-throughput.js b/benchmark/crypto/rsa-encrypt-decrypt-throughput.js
index 13153c20cad569..9791160263c9ec 100644
--- a/benchmark/crypto/rsa-encrypt-decrypt-throughput.js
+++ b/benchmark/crypto/rsa-encrypt-decrypt-throughput.js
@@ -35,7 +35,7 @@ function StreamWrite(algo, keylen, message, n, len) {
const privateKey = RSA_PrivatePem[keylen];
const publicKey = RSA_PublicPem[keylen];
- for (var i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
const enc = crypto.privateEncrypt(privateKey, message);
crypto.publicDecrypt(publicKey, enc);
}
diff --git a/benchmark/dgram/array-vs-concat.js b/benchmark/dgram/array-vs-concat.js
index d260a48063d489..ae9a759a983c04 100644
--- a/benchmark/dgram/array-vs-concat.js
+++ b/benchmark/dgram/array-vs-concat.js
@@ -18,12 +18,12 @@ const bench = common.createBenchmark(main, {
function main({ dur, len, num, type, chunks }) {
const chunk = [];
- for (var i = 0; i < chunks; i++) {
+ for (let i = 0; i < chunks; i++) {
chunk.push(Buffer.allocUnsafe(Math.round(len / chunks)));
}
// Server
- var sent = 0;
+ let sent = 0;
const socket = dgram.createSocket('udp4');
const onsend = type === 'concat' ? onsendConcat : onsendMulti;
@@ -32,7 +32,7 @@ function main({ dur, len, num, type, chunks }) {
// The setImmediate() is necessary to have event loop progress on OSes
// that only perform synchronous I/O on nonblocking UDP sockets.
setImmediate(() => {
- for (var i = 0; i < num; i++) {
+ for (let i = 0; i < num; i++) {
socket.send(Buffer.concat(chunk), PORT, '127.0.0.1', onsend);
}
});
@@ -44,7 +44,7 @@ function main({ dur, len, num, type, chunks }) {
// The setImmediate() is necessary to have event loop progress on OSes
// that only perform synchronous I/O on nonblocking UDP sockets.
setImmediate(() => {
- for (var i = 0; i < num; i++) {
+ for (let i = 0; i < num; i++) {
socket.send(chunk, PORT, '127.0.0.1', onsend);
}
});
diff --git a/benchmark/dgram/bind-params.js b/benchmark/dgram/bind-params.js
index ea1f430eed929b..5f7999f7a39241 100644
--- a/benchmark/dgram/bind-params.js
+++ b/benchmark/dgram/bind-params.js
@@ -15,11 +15,10 @@ const noop = () => {};
function main({ n, port, address }) {
port = port === 'true' ? 0 : undefined;
address = address === 'true' ? '0.0.0.0' : undefined;
- var i;
if (port !== undefined && address !== undefined) {
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
dgram.createSocket('udp4').bind(port, address)
.on('error', noop)
.unref();
@@ -27,7 +26,7 @@ function main({ n, port, address }) {
bench.end(n);
} else if (port !== undefined) {
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
dgram.createSocket('udp4')
.bind(port)
.on('error', noop)
@@ -36,7 +35,7 @@ function main({ n, port, address }) {
bench.end(n);
} else if (port === undefined && address === undefined) {
bench.start();
- for (i = 0; i < n; i++) {
+ for (let i = 0; i < n; i++) {
dgram.createSocket('udp4')
.bind()
.on('error', noop)
diff --git a/benchmark/dgram/multi-buffer.js b/benchmark/dgram/multi-buffer.js
index 7b69a82255ed4b..add77cd7845ce1 100644
--- a/benchmark/dgram/multi-buffer.js
+++ b/benchmark/dgram/multi-buffer.js
@@ -18,11 +18,11 @@ const bench = common.createBenchmark(main, {
function main({ dur, len, num, type, chunks }) {
const chunk = [];
- for (var i = 0; i < chunks; i++) {
+ for (let i = 0; i < chunks; i++) {
chunk.push(Buffer.allocUnsafe(Math.round(len / chunks)));
}
- var sent = 0;
- var received = 0;
+ let sent = 0;
+ let received = 0;
const socket = dgram.createSocket('udp4');
function onsend() {
@@ -30,7 +30,7 @@ function main({ dur, len, num, type, chunks }) {
// The setImmediate() is necessary to have event loop progress on OSes
// that only perform synchronous I/O on nonblocking UDP sockets.
setImmediate(() => {
- for (var i = 0; i < num; i++) {
+ for (let i = 0; i < num; i++) {
socket.send(chunk, PORT, '127.0.0.1', onsend);
}
});
diff --git a/benchmark/dgram/offset-length.js b/benchmark/dgram/offset-length.js
index 696fa6a7a0c0bd..eea0b75b773ca8 100644
--- a/benchmark/dgram/offset-length.js
+++ b/benchmark/dgram/offset-length.js
@@ -17,8 +17,8 @@ const bench = common.createBenchmark(main, {
function main({ dur, len, num, type }) {
const chunk = Buffer.allocUnsafe(len);
- var sent = 0;
- var received = 0;
+ let sent = 0;
+ let received = 0;
const socket = dgram.createSocket('udp4');
function onsend() {
@@ -26,7 +26,7 @@ function main({ dur, len, num, type }) {
// The setImmediate() is necessary to have event loop progress on OSes
// that only perform synchronous I/O on nonblocking UDP sockets.
setImmediate(() => {
- for (var i = 0; i < num; i++) {
+ for (let i = 0; i < num; i++) {
socket.send(chunk, 0, chunk.length, PORT, '127.0.0.1', onsend);
}
});
diff --git a/benchmark/dgram/single-buffer.js b/benchmark/dgram/single-buffer.js
index 5c95b17887d37a..b02f785bb052f2 100644
--- a/benchmark/dgram/single-buffer.js
+++ b/benchmark/dgram/single-buffer.js
@@ -17,8 +17,8 @@ const bench = common.createBenchmark(main, {
function main({ dur, len, num, type }) {
const chunk = Buffer.allocUnsafe(len);
- var sent = 0;
- var received = 0;
+ let sent = 0;
+ let received = 0;
const socket = dgram.createSocket('udp4');
function onsend() {
@@ -26,7 +26,7 @@ function main({ dur, len, num, type }) {
// The setImmediate() is necessary to have event loop progress on OSes
// that only perform synchronous I/O on nonblocking UDP sockets.
setImmediate(() => {
- for (var i = 0; i < num; i++) {
+ for (let i = 0; i < num; i++) {
socket.send(chunk, PORT, '127.0.0.1', onsend);
}
});
diff --git a/benchmark/fs/bench-opendir.js b/benchmark/fs/bench-opendir.js
index 419c3a231a850b..20e178d9cc5236 100644
--- a/benchmark/fs/bench-opendir.js
+++ b/benchmark/fs/bench-opendir.js
@@ -7,10 +7,11 @@ const path = require('path');
const bench = common.createBenchmark(main, {
n: [100],
dir: [ 'lib', 'test/parallel'],
- mode: [ 'async', 'sync', 'callback' ]
+ mode: [ 'async', 'sync', 'callback' ],
+ bufferSize: [ 4, 32, 1024 ]
});
-async function main({ n, dir, mode }) {
+async function main({ n, dir, mode, bufferSize }) {
const fullPath = path.resolve(__dirname, '../../', dir);
bench.start();
@@ -18,11 +19,12 @@ async function main({ n, dir, mode }) {
let counter = 0;
for (let i = 0; i < n; i++) {
if (mode === 'async') {
+ const dir = await fs.promises.opendir(fullPath, { bufferSize });
// eslint-disable-next-line no-unused-vars
- for await (const entry of await fs.promises.opendir(fullPath))
+ for await (const entry of dir)
counter++;
} else if (mode === 'callback') {
- const dir = await fs.promises.opendir(fullPath);
+ const dir = await fs.promises.opendir(fullPath, { bufferSize });
await new Promise((resolve, reject) => {
function read() {
dir.read((err, entry) => {
@@ -40,7 +42,7 @@ async function main({ n, dir, mode }) {
read();
});
} else {
- const dir = fs.opendirSync(fullPath);
+ const dir = fs.opendirSync(fullPath, { bufferSize });
while (dir.readSync() !== null)
counter++;
dir.closeSync();
diff --git a/benchmark/net/net-pipe.js b/benchmark/net/net-pipe.js
index f19e30b5450785..06426129f7f271 100644
--- a/benchmark/net/net-pipe.js
+++ b/benchmark/net/net-pipe.js
@@ -6,7 +6,7 @@ const net = require('net');
const PORT = common.PORT;
const bench = common.createBenchmark(main, {
- len: [64, 102400, 1024 * 1024 * 16],
+ len: [2, 64, 102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5],
});
diff --git a/benchmark/run.js b/benchmark/run.js
index 2eb1ab1a4b0905..8e81a2c5e16ab7 100644
--- a/benchmark/run.js
+++ b/benchmark/run.js
@@ -8,10 +8,13 @@ const cli = CLI(`usage: ./node run.js [options] [--] ...
Run each benchmark in the directory a single time, more than one
directory can be specified.
- --filter pattern string to filter benchmark scripts
+ --filter pattern includes only benchmark scripts matching
+ (can be repeated)
+ --exclude pattern excludes scripts matching (can be
+ repeated)
--set variable=value set benchmark variable (can be repeated)
--format [simple|csv] optional value that specifies the output format
-`, { arrayArgs: ['set'] });
+`, { arrayArgs: ['set', 'filter', 'exclude'] });
const benchmarks = cli.benchmarks();
if (benchmarks.length === 0) {
diff --git a/benchmark/streams/writable-manywrites.js b/benchmark/streams/writable-manywrites.js
index 0ed38d0357a438..049bf8eb281db2 100644
--- a/benchmark/streams/writable-manywrites.js
+++ b/benchmark/streams/writable-manywrites.js
@@ -5,23 +5,39 @@ const Writable = require('stream').Writable;
const bench = common.createBenchmark(main, {
n: [2e6],
- sync: ['yes', 'no']
+ sync: ['yes', 'no'],
+ writev: ['yes', 'no'],
+ callback: ['yes', 'no']
});
-function main({ n, sync }) {
+function main({ n, sync, writev, callback }) {
const b = Buffer.allocUnsafe(1024);
const s = new Writable();
sync = sync === 'yes';
- s._write = function(chunk, encoding, cb) {
+
+ const writecb = (cb) => {
if (sync)
cb();
else
process.nextTick(cb);
};
+ if (writev === 'yes') {
+ s._writev = (chunks, cb) => writecb(cb);
+ } else {
+ s._write = (chunk, encoding, cb) => writecb(cb);
+ }
+
+ const cb = callback === 'yes' ? () => {} : null;
+
bench.start();
- for (var k = 0; k < n; ++k) {
- s.write(b);
+
+ let k = 0;
+ function run() {
+ while (k++ < n && s.write(b, cb));
+ if (k >= n)
+ bench.end(n);
}
- bench.end(n);
+ s.on('drain', run);
+ run();
}
diff --git a/benchmark/tls/secure-pair.js b/benchmark/tls/secure-pair.js
index c0409febacda00..c52f4cbf918a1d 100644
--- a/benchmark/tls/secure-pair.js
+++ b/benchmark/tls/secure-pair.js
@@ -2,8 +2,8 @@
const common = require('../common.js');
const bench = common.createBenchmark(main, {
dur: [5],
- securing: ['SecurePair', 'TLSSocket'],
- size: [2, 1024, 1024 * 1024]
+ securing: ['SecurePair', 'TLSSocket', 'clear'],
+ size: [2, 100, 1024, 1024 * 1024]
});
const fixtures = require('../../test/common/fixtures');
@@ -37,7 +37,8 @@ function main({ dur, size, securing }) {
isServer: false,
rejectUnauthorized: false,
};
- const conn = tls.connect(clientOptions, () => {
+ const network = securing === 'clear' ? net : tls;
+ const conn = network.connect(clientOptions, () => {
setTimeout(() => {
const mbits = (received * 8) / (1024 * 1024);
bench.end(mbits);
@@ -69,6 +70,9 @@ function main({ dur, size, securing }) {
case 'TLSSocket':
secureTLSSocket(conn, client);
break;
+ case 'clear':
+ conn.pipe(client);
+ break;
default:
throw new Error('Invalid securing method');
}
diff --git a/benchmark/util/format.js b/benchmark/util/format.js
index 44e950a6ca6522..976e0f4e655486 100644
--- a/benchmark/util/format.js
+++ b/benchmark/util/format.js
@@ -13,6 +13,8 @@ const inputs = {
'no-replace-2': ['foobar', 'yeah', 'mensch', 5],
'only-objects': [{ msg: 'This is an error' }, { msg: 'This is an error' }],
'many-%': ['replace%%%%s%%%%many%s%s%s', 'percent'],
+ 'object-to-string': ['foo %s bar', { toString() { return 'bla'; } }],
+ 'object-%s': ['foo %s bar', { a: true, b: false }],
};
const bench = common.createBenchmark(main, {
diff --git a/benchmark/util/inspect-proxy.js b/benchmark/util/inspect-proxy.js
index dde86941ff42a3..02379cdc770f3b 100644
--- a/benchmark/util/inspect-proxy.js
+++ b/benchmark/util/inspect-proxy.js
@@ -3,13 +3,21 @@
const util = require('util');
const common = require('../common.js');
-const bench = common.createBenchmark(main, { n: [2e4] });
+const bench = common.createBenchmark(main, {
+ n: [1e5],
+ showProxy: [0, 1],
+ isProxy: [0, 1]
+});
-function main({ n }) {
- const proxyA = new Proxy({}, { get: () => {} });
- const proxyB = new Proxy(() => {}, {});
+function main({ n, showProxy, isProxy }) {
+ let proxyA = {};
+ let proxyB = () => {};
+ if (isProxy) {
+ proxyA = new Proxy(proxyA, { get: () => {} });
+ proxyB = new Proxy(proxyB, {});
+ }
bench.start();
for (let i = 0; i < n; i += 1)
- util.inspect({ a: proxyA, b: proxyB }, { showProxy: true });
+ util.inspect({ a: proxyA, b: proxyB }, { showProxy });
bench.end(n);
}
diff --git a/doc/guides/writing-and-running-benchmarks.md b/benchmark/writing-and-running-benchmarks.md
similarity index 83%
rename from doc/guides/writing-and-running-benchmarks.md
rename to benchmark/writing-and-running-benchmarks.md
index 6097830aeeba1f..1db72d22de5324 100644
--- a/doc/guides/writing-and-running-benchmarks.md
+++ b/benchmark/writing-and-running-benchmarks.md
@@ -8,6 +8,7 @@
* [Running benchmarks](#running-benchmarks)
* [Running individual benchmarks](#running-individual-benchmarks)
* [Running all benchmarks](#running-all-benchmarks)
+ * [Filtering benchmarks](#filtering-benchmarks)
* [Comparing Node.js versions](#comparing-nodejs-versions)
* [Comparing parameters](#comparing-parameters)
* [Running Benchmarks on the CI](#running-benchmarks-on-the-ci)
@@ -149,6 +150,87 @@ It is possible to execute more groups by adding extra process arguments.
$ node benchmark/run.js assert async_hooks
```
+#### Filtering benchmarks
+
+`benchmark/run.js` and `benchmark/compare.js` have `--filter pattern` and
+`--exclude pattern` options, which can be used to run a subset of benchmarks or
+to exclude specific benchmarks from the execution, respectively.
+
+```console
+$ node benchmark/run.js --filter "deepequal-b" assert
+
+assert/deepequal-buffer.js
+assert/deepequal-buffer.js method="deepEqual" strict=0 len=100 n=20000: 773,200.4995493788
+assert/deepequal-buffer.js method="notDeepEqual" strict=0 len=100 n=20000: 964,411.712953848
+
+$ node benchmark/run.js --exclude "deepequal-b" assert
+
+assert/deepequal-map.js
+assert/deepequal-map.js method="deepEqual_primitiveOnly" strict=0 len=500 n=500: 20,445.06368453332
+assert/deepequal-map.js method="deepEqual_objectOnly" strict=0 len=500 n=500: 1,393.3481642240833
+...
+
+assert/deepequal-object.js
+assert/deepequal-object.js method="deepEqual" strict=0 size=100 n=5000: 1,053.1950937538475
+assert/deepequal-object.js method="notDeepEqual" strict=0 size=100 n=5000: 9,734.193251965213
+...
+```
+
+`--filter` and `--exclude` can be repeated to provide multiple patterns.
+
+```console
+$ node benchmark/run.js --filter "deepequal-b" --filter "deepequal-m" assert
+
+assert/deepequal-buffer.js
+assert/deepequal-buffer.js method="deepEqual" strict=0 len=100 n=20000: 773,200.4995493788
+assert/deepequal-buffer.js method="notDeepEqual" strict=0 len=100 n=20000: 964,411.712953848
+
+assert/deepequal-map.js
+assert/deepequal-map.js method="deepEqual_primitiveOnly" strict=0 len=500 n=500: 20,445.06368453332
+assert/deepequal-map.js method="deepEqual_objectOnly" strict=0 len=500 n=500: 1,393.3481642240833
+
+$ node benchmark/run.js --exclude "deepequal-b" --exclude "deepequal-m" assert
+
+assert/deepequal-object.js
+assert/deepequal-object.js method="deepEqual" strict=0 size=100 n=5000: 1,053.1950937538475
+assert/deepequal-object.js method="notDeepEqual" strict=0 size=100 n=5000: 9,734.193251965213
+...
+
+assert/deepequal-prims-and-objs-big-array-set.js
+assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual_Array" strict=0 len=20000 n=25 primitive="string": 865.2977195251661
+assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual_Array" strict=0 len=20000 n=25 primitive="string": 827.8297281403861
+assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual_Set" strict=0 len=20000 n=25 primitive="string": 28,826.618268696366
+...
+```
+
+If `--filter` and `--exclude` are used together, `--filter` is applied first,
+and `--exclude` is applied on the result of `--filter`:
+
+```console
+$ node benchmark/run.js --filter "bench-" process
+
+process/bench-env.js
+process/bench-env.js operation="get" n=1000000: 2,356,946.0770617095
+process/bench-env.js operation="set" n=1000000: 1,295,176.3266261867
+process/bench-env.js operation="enumerate" n=1000000: 24,592.32231990992
+process/bench-env.js operation="query" n=1000000: 3,625,787.2150573144
+process/bench-env.js operation="delete" n=1000000: 1,521,131.5742806569
+
+process/bench-hrtime.js
+process/bench-hrtime.js type="raw" n=1000000: 13,178,002.113936031
+process/bench-hrtime.js type="diff" n=1000000: 11,585,435.712423025
+process/bench-hrtime.js type="bigint" n=1000000: 13,342,884.703919787
+
+$ node benchmark/run.js --filter "bench-" --exclude "hrtime" process
+
+process/bench-env.js
+process/bench-env.js operation="get" n=1000000: 2,356,946.0770617095
+process/bench-env.js operation="set" n=1000000: 1,295,176.3266261867
+process/bench-env.js operation="enumerate" n=1000000: 24,592.32231990992
+process/bench-env.js operation="query" n=1000000: 3,625,787.2150573144
+process/bench-env.js operation="delete" n=1000000: 1,521,131.5742806569
+```
+
### Comparing Node.js versions
To compare the effect of a new Node.js version use the `compare.js` tool. This
diff --git a/common.gypi b/common.gypi
index b86e5e05d7df9a..8c9076b7352d81 100644
--- a/common.gypi
+++ b/common.gypi
@@ -38,7 +38,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.16',
+ 'v8_embedder_string': '-node.31',
##### V8 defaults for Node.js #####
@@ -161,8 +161,8 @@
'ldflags': [ '-Wl,-bbigtoc' ],
}],
['OS == "android"', {
- 'cflags': [ '-fPIE' ],
- 'ldflags': [ '-fPIE', '-pie' ]
+ 'cflags': [ '-fPIC' ],
+ 'ldflags': [ '-fPIC' ]
}],
],
'msvs_settings': {
@@ -221,8 +221,8 @@
],
},],
['OS == "android"', {
- 'cflags': [ '-fPIE' ],
- 'ldflags': [ '-fPIE', '-pie' ]
+ 'cflags': [ '-fPIC' ],
+ 'ldflags': [ '-fPIC' ]
}],
],
'msvs_settings': {
@@ -361,6 +361,7 @@
[ 'OS in "linux freebsd openbsd solaris android aix cloudabi"', {
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions', '-std=gnu++1y' ],
+ 'defines': [ '__STDC_FORMAT_MACROS' ],
'ldflags': [ '-rdynamic' ],
'target_conditions': [
# The 1990s toolchain on SmartOS can't handle thin archives.
diff --git a/configure.py b/configure.py
index 20cce214dbb113..6537a62d3954d8 100755
--- a/configure.py
+++ b/configure.py
@@ -401,13 +401,12 @@
parser.add_option('--use-largepages',
action='store_true',
dest='node_use_large_pages',
- help='build with Large Pages support. This feature is supported only on Linux kernel' +
- '>= 2.6.38 with Transparent Huge pages enabled and FreeBSD')
+ help='This option has no effect. --use-largepages is now a runtime option.')
parser.add_option('--use-largepages-script-lld',
action='store_true',
dest='node_use_large_pages_script_lld',
- help='link against the LLVM ld linker script. Implies -fuse-ld=lld in the linker flags')
+ help='This option has no effect. --use-largepages is now a runtime option.')
intl_optgroup.add_option('--with-intl',
action='store',
@@ -444,6 +443,14 @@
'the icu4c source archive. '
'v%d.x or later recommended.' % icu_versions['minimum_icu'])
+intl_optgroup.add_option('--with-icu-default-data-dir',
+ action='store',
+ dest='with_icu_default_data_dir',
+ help='Path to the icuXXdt{lb}.dat file. If unspecified, ICU data will '
+ 'only be read if the NODE_ICU_DATA environment variable or the '
+ '--icu-data-dir runtime argument is used. This option has effect '
+ 'only when Node.js is built with --with-intl=small-icu.')
+
parser.add_option('--with-ltcg',
action='store_true',
dest='with_ltcg',
@@ -454,6 +461,11 @@
dest='without_node_snapshot',
help='Turn off V8 snapshot integration. Currently experimental.')
+parser.add_option('--without-node-code-cache',
+ action='store_true',
+ dest='without_node_code_cache',
+ help='Turn off V8 Code cache integration.')
+
intl_optgroup.add_option('--download',
action='store',
dest='download_list',
@@ -975,10 +987,17 @@ def configure_node(o):
if not options.without_node_snapshot:
o['variables']['node_use_node_snapshot'] = b(
- not cross_compiling and want_snapshots)
+ not cross_compiling and want_snapshots and not options.shared)
else:
o['variables']['node_use_node_snapshot'] = 'false'
+ if not options.without_node_code_cache:
+ # TODO(refack): fix this when implementing embedded code-cache when cross-compiling.
+ o['variables']['node_use_node_code_cache'] = b(
+ not cross_compiling and not options.shared)
+ else:
+ o['variables']['node_use_node_code_cache'] = 'false'
+
if target_arch == 'arm':
configure_arm(o)
elif target_arch in ('mips', 'mipsel', 'mips64el'):
@@ -1041,27 +1060,12 @@ def configure_node(o):
else:
o['variables']['node_use_dtrace'] = 'false'
- if options.node_use_large_pages and not flavor in ('linux', 'freebsd', 'mac'):
- raise Exception(
- 'Large pages are supported only on Linux, FreeBSD and MacOS Systems.')
- if options.node_use_large_pages and flavor in ('linux', 'freebsd', 'mac'):
- if options.shared or options.enable_static:
- raise Exception(
- 'Large pages are supported only while creating node executable.')
- if target_arch!="x64":
- raise Exception(
- 'Large pages are supported only x64 platform.')
- if flavor == 'mac':
- info('macOS server with 32GB or more is recommended')
- if flavor == 'linux':
- # Example full version string: 2.6.32-696.28.1.el6.x86_64
- FULL_KERNEL_VERSION=os.uname()[2]
- KERNEL_VERSION=FULL_KERNEL_VERSION.split('-')[0]
- if KERNEL_VERSION < "2.6.38" and flavor == 'linux':
- raise Exception(
- 'Large pages need Linux kernel version >= 2.6.38')
- o['variables']['node_use_large_pages'] = b(options.node_use_large_pages)
- o['variables']['node_use_large_pages_script_lld'] = b(options.node_use_large_pages_script_lld)
+ if options.node_use_large_pages or options.node_use_large_pages_script_lld:
+ warn('''The `--use-largepages` and `--use-largepages-script-lld` options
+ have no effect during build time. Support for mapping to large pages is
+ now a runtime option of Node.js. Run `node --use-largepages` or add
+ `--use-largepages` to the `NODE_OPTIONS` environment variable once
+ Node.js is built to enable mapping to large pages.''')
if options.no_ifaddrs:
o['defines'] += ['SUNOS_NO_IFADDRS']
@@ -1099,20 +1103,21 @@ def configure_node(o):
o['variables']['debug_nghttp2'] = 'false'
o['variables']['node_no_browser_globals'] = b(options.no_browser_globals)
- # TODO(refack): fix this when implementing embedded code-cache when cross-compiling.
- if o['variables']['want_separate_host_toolset'] == 0:
- o['variables']['node_code_cache'] = 'yes' # For testing
+
o['variables']['node_shared'] = b(options.shared)
node_module_version = getmoduleversion.get_version()
- if sys.platform == 'darwin':
+ if options.dest_os == 'android':
+ shlib_suffix = 'so'
+ elif sys.platform == 'darwin':
shlib_suffix = '%s.dylib'
elif sys.platform.startswith('aix'):
shlib_suffix = '%s.a'
else:
shlib_suffix = 'so.%s'
+ if '%s' in shlib_suffix:
+ shlib_suffix %= node_module_version
- shlib_suffix %= node_module_version
o['variables']['node_module_version'] = int(node_module_version)
o['variables']['shlib_suffix'] = shlib_suffix
@@ -1373,6 +1378,7 @@ def write_config(data, name):
locs.add('root') # must have root
o['variables']['icu_locales'] = ','.join(str(loc) for loc in locs)
# We will check a bit later if we can use the canned deps/icu-small
+ o['variables']['icu_default_data'] = options.with_icu_default_data_dir or ''
elif with_intl == 'full-icu':
# full ICU
o['variables']['v8_enable_i18n_support'] = 1
diff --git a/deps/http_parser/Makefile b/deps/http_parser/Makefile
index 6cf63bd35ea12b..23be2884ea81b3 100644
--- a/deps/http_parser/Makefile
+++ b/deps/http_parser/Makefile
@@ -23,8 +23,8 @@ HELPER ?=
BINEXT ?=
SOLIBNAME = libhttp_parser
SOMAJOR = 2
-SOMINOR = 8
-SOREV = 0
+SOMINOR = 9
+SOREV = 1
ifeq (darwin,$(PLATFORM))
SOEXT ?= dylib
SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)
diff --git a/deps/http_parser/README.md b/deps/http_parser/README.md
index 9c4c9999c2663f..b265d71715f771 100644
--- a/deps/http_parser/README.md
+++ b/deps/http_parser/README.md
@@ -148,7 +148,7 @@ callback in a threadsafe manner. This allows `http_parser` to be used in
multi-threaded contexts.
Example:
-```
+```c
typedef struct {
socket_t sock;
void* buffer;
@@ -184,7 +184,7 @@ void http_parser_thread(socket_t sock) {
parser supplied to callback functions */
parser->data = my_data;
- http_parser_settings settings; / * set up callbacks */
+ http_parser_settings settings; /* set up callbacks */
settings.on_url = my_url_callback;
/* execute parser */
diff --git a/deps/http_parser/bench.c b/deps/http_parser/bench.c
index 5b452fa1cdb6e6..678f5556c59880 100644
--- a/deps/http_parser/bench.c
+++ b/deps/http_parser/bench.c
@@ -20,10 +20,14 @@
*/
#include "http_parser.h"
#include
+#include
#include
#include
#include
+/* 8 gb */
+static const int64_t kBytes = 8LL << 30;
+
static const char data[] =
"POST /joyent/http-parser HTTP/1.1\r\n"
"Host: github.com\r\n"
@@ -38,7 +42,7 @@ static const char data[] =
"Referer: https://github.com/joyent/http-parser\r\n"
"Connection: keep-alive\r\n"
"Transfer-Encoding: chunked\r\n"
- "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n\r\n";
+ "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n";
static const size_t data_len = sizeof(data) - 1;
static int on_info(http_parser* p) {
@@ -67,13 +71,13 @@ int bench(int iter_count, int silent) {
int err;
struct timeval start;
struct timeval end;
- float rps;
if (!silent) {
err = gettimeofday(&start, NULL);
assert(err == 0);
}
+ fprintf(stderr, "req_len=%d\n", (int) data_len);
for (i = 0; i < iter_count; i++) {
size_t parsed;
http_parser_init(&parser, HTTP_REQUEST);
@@ -83,17 +87,27 @@ int bench(int iter_count, int silent) {
}
if (!silent) {
+ double elapsed;
+ double bw;
+ double total;
+
err = gettimeofday(&end, NULL);
assert(err == 0);
fprintf(stdout, "Benchmark result:\n");
- rps = (float) (end.tv_sec - start.tv_sec) +
- (end.tv_usec - start.tv_usec) * 1e-6f;
- fprintf(stdout, "Took %f seconds to run\n", rps);
+ elapsed = (double) (end.tv_sec - start.tv_sec) +
+ (end.tv_usec - start.tv_usec) * 1e-6f;
+
+ total = (double) iter_count * data_len;
+ bw = (double) total / elapsed;
+
+ fprintf(stdout, "%.2f mb | %.2f mb/s | %.2f req/sec | %.2f s\n",
+ (double) total / (1024 * 1024),
+ bw / (1024 * 1024),
+ (double) iter_count / elapsed,
+ elapsed);
- rps = (float) iter_count / rps;
- fprintf(stdout, "%f req/sec\n", rps);
fflush(stdout);
}
@@ -101,11 +115,14 @@ int bench(int iter_count, int silent) {
}
int main(int argc, char** argv) {
+ int64_t iterations;
+
+ iterations = kBytes / (int64_t) data_len;
if (argc == 2 && strcmp(argv[1], "infinite") == 0) {
for (;;)
- bench(5000000, 1);
+ bench(iterations, 1);
return 0;
} else {
- return bench(5000000, 0);
+ return bench(iterations, 0);
}
}
diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c
index 46764bced09478..2ea228eb0fdc77 100644
--- a/deps/http_parser/http_parser.c
+++ b/deps/http_parser/http_parser.c
@@ -51,6 +51,7 @@ static uint32_t max_header_size = HTTP_MAX_HEADER_SIZE;
#define SET_ERRNO(e) \
do { \
+ parser->nread = nread; \
parser->http_errno = (e); \
} while(0)
@@ -58,6 +59,7 @@ do { \
#define UPDATE_STATE(V) p_state = (enum state) (V);
#define RETURN(V) \
do { \
+ parser->nread = nread; \
parser->state = CURRENT_STATE(); \
return (V); \
} while (0);
@@ -151,8 +153,8 @@ do { \
*/
#define COUNT_HEADER_SIZE(V) \
do { \
- parser->nread += (V); \
- if (UNLIKELY(parser->nread > max_header_size)) { \
+ nread += (uint32_t)(V); \
+ if (UNLIKELY(nread > max_header_size)) { \
SET_ERRNO(HPE_HEADER_OVERFLOW); \
goto error; \
} \
@@ -194,7 +196,7 @@ static const char tokens[256] = {
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
0, 0, 0, 0, 0, 0, 0, 0,
/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
- 0, '!', 0, '#', '$', '%', '&', '\'',
+ ' ', '!', 0, '#', '$', '%', '&', '\'',
/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
0, 0, '*', '+', 0, '-', '.', 0,
/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
@@ -314,6 +316,8 @@ enum state
, s_req_http_HT
, s_req_http_HTT
, s_req_http_HTTP
+ , s_req_http_I
+ , s_req_http_IC
, s_req_http_major
, s_req_http_dot
, s_req_http_minor
@@ -421,14 +425,14 @@ enum http_host_state
(c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
(c) == '$' || (c) == ',')
-#define STRICT_TOKEN(c) (tokens[(unsigned char)c])
+#define STRICT_TOKEN(c) ((c == ' ') ? 0 : tokens[(unsigned char)c])
#if HTTP_PARSER_STRICT
-#define TOKEN(c) (tokens[(unsigned char)c])
+#define TOKEN(c) STRICT_TOKEN(c)
#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c))
#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
#else
-#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c])
+#define TOKEN(c) tokens[(unsigned char)c]
#define IS_URL_CHAR(c) \
(BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
#define IS_HOST_CHAR(c) \
@@ -542,7 +546,7 @@ parse_url_char(enum state s, const char ch)
return s_dead;
}
- /* FALLTHROUGH */
+ /* fall through */
case s_req_server_start:
case s_req_server:
if (ch == '/') {
@@ -646,6 +650,7 @@ size_t http_parser_execute (http_parser *parser,
const char *status_mark = 0;
enum state p_state = (enum state) parser->state;
const unsigned int lenient = parser->lenient_http_headers;
+ uint32_t nread = parser->nread;
/* We're in an error state. Don't bother doing anything. */
if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
@@ -757,21 +762,16 @@ size_t http_parser_execute (http_parser *parser,
case s_start_res:
{
+ if (ch == CR || ch == LF)
+ break;
parser->flags = 0;
parser->content_length = ULLONG_MAX;
- switch (ch) {
- case 'H':
- UPDATE_STATE(s_res_H);
- break;
-
- case CR:
- case LF:
- break;
-
- default:
- SET_ERRNO(HPE_INVALID_CONSTANT);
- goto error;
+ if (ch == 'H') {
+ UPDATE_STATE(s_res_H);
+ } else {
+ SET_ERRNO(HPE_INVALID_CONSTANT);
+ goto error;
}
CALLBACK_NOTIFY(message_begin);
@@ -1088,11 +1088,17 @@ size_t http_parser_execute (http_parser *parser,
case s_req_http_start:
switch (ch) {
+ case ' ':
+ break;
case 'H':
UPDATE_STATE(s_req_http_H);
break;
- case ' ':
- break;
+ case 'I':
+ if (parser->method == HTTP_SOURCE) {
+ UPDATE_STATE(s_req_http_I);
+ break;
+ }
+ /* fall through */
default:
SET_ERRNO(HPE_INVALID_CONSTANT);
goto error;
@@ -1114,6 +1120,16 @@ size_t http_parser_execute (http_parser *parser,
UPDATE_STATE(s_req_http_HTTP);
break;
+ case s_req_http_I:
+ STRICT_CHECK(ch != 'C');
+ UPDATE_STATE(s_req_http_IC);
+ break;
+
+ case s_req_http_IC:
+ STRICT_CHECK(ch != 'E');
+ UPDATE_STATE(s_req_http_HTTP); /* Treat "ICE" as "HTTP". */
+ break;
+
case s_req_http_HTTP:
STRICT_CHECK(ch != '/');
UPDATE_STATE(s_req_http_major);
@@ -1240,8 +1256,14 @@ size_t http_parser_execute (http_parser *parser,
break;
switch (parser->header_state) {
- case h_general:
+ case h_general: {
+ size_t limit = data + len - p;
+ limit = MIN(limit, max_header_size);
+ while (p+1 < data + limit && TOKEN(p[1])) {
+ p++;
+ }
break;
+ }
case h_C:
parser->index++;
@@ -1341,13 +1363,14 @@ size_t http_parser_execute (http_parser *parser,
}
}
- COUNT_HEADER_SIZE(p - start);
-
if (p == data + len) {
--p;
+ COUNT_HEADER_SIZE(p - start);
break;
}
+ COUNT_HEADER_SIZE(p - start);
+
if (ch == ':') {
UPDATE_STATE(s_header_value_discard_ws);
CALLBACK_DATA(header_field);
@@ -1371,7 +1394,7 @@ size_t http_parser_execute (http_parser *parser,
break;
}
- /* FALLTHROUGH */
+ /* fall through */
case s_header_value_start:
{
@@ -1413,6 +1436,11 @@ size_t http_parser_execute (http_parser *parser,
parser->header_state = h_content_length_num;
break;
+ /* when obsolete line folding is encountered for content length
+ * continue to the s_header_value state */
+ case h_content_length_ws:
+ break;
+
case h_connection:
/* looking for 'Connection: keep-alive' */
if (c == 'k') {
@@ -1468,29 +1496,24 @@ size_t http_parser_execute (http_parser *parser,
switch (h_state) {
case h_general:
- {
- const char* p_cr;
- const char* p_lf;
- size_t limit = data + len - p;
-
- limit = MIN(limit, max_header_size);
-
- p_cr = (const char*) memchr(p, CR, limit);
- p_lf = (const char*) memchr(p, LF, limit);
- if (p_cr != NULL) {
- if (p_lf != NULL && p_cr >= p_lf)
- p = p_lf;
- else
- p = p_cr;
- } else if (UNLIKELY(p_lf != NULL)) {
- p = p_lf;
- } else {
- p = data + len;
+ {
+ const char* limit = p + MIN(data + len - p, max_header_size);
+
+ for (; p != limit; p++) {
+ ch = *p;
+ if (ch == CR || ch == LF) {
+ --p;
+ break;
+ }
+ if (!lenient && !IS_HEADER_CHAR(ch)) {
+ SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
+ goto error;
+ }
+ }
+ if (p == data + len)
+ --p;
+ break;
}
- --p;
-
- break;
- }
case h_connection:
case h_transfer_encoding:
@@ -1500,7 +1523,7 @@ size_t http_parser_execute (http_parser *parser,
case h_content_length:
if (ch == ' ') break;
h_state = h_content_length_num;
- /* FALLTHROUGH */
+ /* fall through */
case h_content_length_num:
{
@@ -1636,10 +1659,10 @@ size_t http_parser_execute (http_parser *parser,
}
parser->header_state = h_state;
- COUNT_HEADER_SIZE(p - start);
-
if (p == data + len)
--p;
+
+ COUNT_HEADER_SIZE(p - start);
break;
}
@@ -1657,6 +1680,10 @@ size_t http_parser_execute (http_parser *parser,
case s_header_value_lws:
{
if (ch == ' ' || ch == '\t') {
+ if (parser->header_state == h_content_length_num) {
+ /* treat obsolete line folding as space */
+ parser->header_state = h_content_length_ws;
+ }
UPDATE_STATE(s_header_value_start);
REEXECUTE();
}
@@ -1709,6 +1736,11 @@ size_t http_parser_execute (http_parser *parser,
case h_transfer_encoding_chunked:
parser->flags |= F_CHUNKED;
break;
+ case h_content_length:
+ /* do not allow empty content length */
+ SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+ goto error;
+ break;
default:
break;
}
@@ -1772,7 +1804,7 @@ size_t http_parser_execute (http_parser *parser,
case 2:
parser->upgrade = 1;
- /* FALLTHROUGH */
+ /* fall through */
case 1:
parser->flags |= F_SKIPBODY;
break;
@@ -1796,6 +1828,7 @@ size_t http_parser_execute (http_parser *parser,
STRICT_CHECK(ch != LF);
parser->nread = 0;
+ nread = 0;
hasBody = parser->flags & F_CHUNKED ||
(parser->content_length > 0 && parser->content_length != ULLONG_MAX);
@@ -1890,7 +1923,7 @@ size_t http_parser_execute (http_parser *parser,
case s_chunk_size_start:
{
- assert(parser->nread == 1);
+ assert(nread == 1);
assert(parser->flags & F_CHUNKED);
unhex_val = unhex[(unsigned char)ch];
@@ -1958,6 +1991,7 @@ size_t http_parser_execute (http_parser *parser,
STRICT_CHECK(ch != LF);
parser->nread = 0;
+ nread = 0;
if (parser->content_length == 0) {
parser->flags |= F_TRAILING;
@@ -2004,6 +2038,7 @@ size_t http_parser_execute (http_parser *parser,
assert(parser->flags & F_CHUNKED);
STRICT_CHECK(ch != LF);
parser->nread = 0;
+ nread = 0;
UPDATE_STATE(s_chunk_size_start);
CALLBACK_NOTIFY(chunk_complete);
break;
@@ -2015,7 +2050,7 @@ size_t http_parser_execute (http_parser *parser,
}
}
- /* Run callbacks for any marks that we have leftover after we ran our of
+ /* Run callbacks for any marks that we have leftover after we ran out of
* bytes. There should be at most one of these set, so it's OK to invoke
* them in series (unset marks will not result in callbacks).
*
@@ -2097,6 +2132,16 @@ http_method_str (enum http_method m)
return ELEM_AT(method_strings, m, "");
}
+const char *
+http_status_str (enum http_status s)
+{
+ switch (s) {
+#define XX(num, name, string) case HTTP_STATUS_##name: return #string;
+ HTTP_STATUS_MAP(XX)
+#undef XX
+ default: return "";
+ }
+}
void
http_parser_init (http_parser *parser, enum http_parser_type t)
@@ -2157,7 +2202,7 @@ http_parse_host_char(enum http_host_state s, const char ch) {
return s_http_host;
}
- /* FALLTHROUGH */
+ /* fall through */
case s_http_host_v6_end:
if (ch == ':') {
return s_http_host_port_start;
@@ -2170,7 +2215,7 @@ http_parse_host_char(enum http_host_state s, const char ch) {
return s_http_host_v6_end;
}
- /* FALLTHROUGH */
+ /* fall through */
case s_http_host_v6_start:
if (IS_HEX(ch) || ch == ':' || ch == '.') {
return s_http_host_v6;
@@ -2186,7 +2231,7 @@ http_parse_host_char(enum http_host_state s, const char ch) {
return s_http_host_v6_end;
}
- /* FALLTHROUGH */
+ /* fall through */
case s_http_host_v6_zone_start:
/* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */
if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' ||
@@ -2211,12 +2256,13 @@ http_parse_host_char(enum http_host_state s, const char ch) {
static int
http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
- assert(u->field_set & (1 << UF_HOST));
enum http_host_state s;
const char *p;
size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
+ assert(u->field_set & (1 << UF_HOST));
+
u->field_data[UF_HOST].len = 0;
s = found_at ? s_http_userinfo_start : s_http_host_start;
@@ -2231,14 +2277,14 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
switch(new_s) {
case s_http_host:
if (s != s_http_host) {
- u->field_data[UF_HOST].off = p - buf;
+ u->field_data[UF_HOST].off = (uint16_t)(p - buf);
}
u->field_data[UF_HOST].len++;
break;
case s_http_host_v6:
if (s != s_http_host_v6) {
- u->field_data[UF_HOST].off = p - buf;
+ u->field_data[UF_HOST].off = (uint16_t)(p - buf);
}
u->field_data[UF_HOST].len++;
break;
@@ -2250,7 +2296,7 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
case s_http_host_port:
if (s != s_http_host_port) {
- u->field_data[UF_PORT].off = p - buf;
+ u->field_data[UF_PORT].off = (uint16_t)(p - buf);
u->field_data[UF_PORT].len = 0;
u->field_set |= (1 << UF_PORT);
}
@@ -2259,7 +2305,7 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
case s_http_userinfo:
if (s != s_http_userinfo) {
- u->field_data[UF_USERINFO].off = p - buf ;
+ u->field_data[UF_USERINFO].off = (uint16_t)(p - buf);
u->field_data[UF_USERINFO].len = 0;
u->field_set |= (1 << UF_USERINFO);
}
@@ -2304,6 +2350,10 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
enum http_parser_url_fields uf, old_uf;
int found_at = 0;
+ if (buflen == 0) {
+ return 1;
+ }
+
u->port = u->field_set = 0;
s = is_connect ? s_req_server_start : s_req_spaces_before_url;
old_uf = UF_MAX;
@@ -2331,7 +2381,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
case s_req_server_with_at:
found_at = 1;
- /* FALLTHROUGH */
+ /* fall through */
case s_req_server:
uf = UF_HOST;
break;
@@ -2359,7 +2409,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
continue;
}
- u->field_data[uf].off = p - buf;
+ u->field_data[uf].off = (uint16_t)(p - buf);
u->field_data[uf].len = 1;
u->field_set |= (1 << uf);
@@ -2422,6 +2472,7 @@ http_parser_pause(http_parser *parser, int paused) {
*/
if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
+ uint32_t nread = parser->nread; /* used by the SET_ERRNO macro */
SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
} else {
assert(0 && "Attempting to pause parser in error state");
diff --git a/deps/http_parser/http_parser.h b/deps/http_parser/http_parser.h
index ea7bafef2c3178..471250bc798cdc 100644
--- a/deps/http_parser/http_parser.h
+++ b/deps/http_parser/http_parser.h
@@ -26,8 +26,8 @@ extern "C" {
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
-#define HTTP_PARSER_VERSION_MINOR 8
-#define HTTP_PARSER_VERSION_PATCH 0
+#define HTTP_PARSER_VERSION_MINOR 9
+#define HTTP_PARSER_VERSION_PATCH 1
#include
#if defined(_WIN32) && !defined(__MINGW32__) && \
@@ -407,6 +407,9 @@ int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
+/* Returns a string version of the HTTP status code. */
+const char *http_status_str(enum http_status s);
+
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c
index cb445cea860701..0140a18b7a2c66 100644
--- a/deps/http_parser/test.c
+++ b/deps/http_parser/test.c
@@ -27,9 +27,7 @@
#include
#if defined(__APPLE__)
-# undef strlcat
# undef strlncpy
-# undef strlcpy
#endif /* defined(__APPLE__) */
#undef TRUE
@@ -43,7 +41,9 @@
#define MIN(a,b) ((a) < (b) ? (a) : (b))
-static http_parser *parser;
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
+
+static http_parser parser;
struct message {
const char *name; // for debugging purposes
@@ -153,10 +153,10 @@ const struct message requests[] =
,.body= ""
}
-#define DUMBFUCK 2
-, {.name= "dumbfuck"
+#define DUMBLUCK 2
+, {.name= "dumbluck"
,.type= HTTP_REQUEST
- ,.raw= "GET /dumbfuck HTTP/1.1\r\n"
+ ,.raw= "GET /dumbluck HTTP/1.1\r\n"
"aaaaaaaaaaaaa:++++++++++\r\n"
"\r\n"
,.should_keep_alive= TRUE
@@ -166,8 +166,8 @@ const struct message requests[] =
,.method= HTTP_GET
,.query_string= ""
,.fragment= ""
- ,.request_path= "/dumbfuck"
- ,.request_url= "/dumbfuck"
+ ,.request_path= "/dumbluck"
+ ,.request_url= "/dumbluck"
,.num_headers= 1
,.headers=
{ { "aaaaaaaaaaaaa", "++++++++++" }
@@ -371,13 +371,13 @@ const struct message requests[] =
,.chunk_lengths= { 5, 6 }
}
-#define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11
-, {.name= "with bullshit after the length"
+#define CHUNKED_W_NONSENSE_AFTER_LENGTH 11
+, {.name= "with nonsense after the length"
,.type= HTTP_REQUEST
- ,.raw= "POST /chunked_w_bullshit_after_length HTTP/1.1\r\n"
+ ,.raw= "POST /chunked_w_nonsense_after_length HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
- "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n"
+ "5; ilovew3;whattheluck=aretheseparametersfor\r\nhello\r\n"
"6; blahblah; blah\r\n world\r\n"
"0\r\n"
"\r\n"
@@ -388,8 +388,8 @@ const struct message requests[] =
,.method= HTTP_POST
,.query_string= ""
,.fragment= ""
- ,.request_path= "/chunked_w_bullshit_after_length"
- ,.request_url= "/chunked_w_bullshit_after_length"
+ ,.request_path= "/chunked_w_nonsense_after_length"
+ ,.request_url= "/chunked_w_nonsense_after_length"
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding", "chunked" }
@@ -1174,7 +1174,25 @@ const struct message requests[] =
,.body= ""
}
-, {.name= NULL } /* sentinel */
+#define SOURCE_ICE_REQUEST 42
+, {.name = "source request"
+ ,.type= HTTP_REQUEST
+ ,.raw= "SOURCE /music/sweet/music ICE/1.0\r\n"
+ "Host: example.com\r\n"
+ "\r\n"
+ ,.should_keep_alive= FALSE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 0
+ ,.method= HTTP_SOURCE
+ ,.request_path= "/music/sweet/music"
+ ,.request_url= "/music/sweet/music"
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.num_headers= 1
+ ,.headers= { { "Host", "example.com" } }
+ ,.body= ""
+ }
};
/* * R E S P O N S E S * */
@@ -1952,8 +1970,6 @@ const struct message responses[] =
,.num_chunks_complete= 3
,.chunk_lengths= { 2, 2 }
}
-
-, {.name= NULL } /* sentinel */
};
/* strnlen() is a POSIX.2008 addition. Can't rely on it being available so
@@ -1993,12 +2009,6 @@ strlncat(char *dst, size_t len, const char *src, size_t n)
return slen + dlen;
}
-size_t
-strlcat(char *dst, const char *src, size_t len)
-{
- return strlncat(dst, len, src, (size_t) -1);
-}
-
size_t
strlncpy(char *dst, size_t len, const char *src, size_t n)
{
@@ -2017,16 +2027,10 @@ strlncpy(char *dst, size_t len, const char *src, size_t n)
return slen;
}
-size_t
-strlcpy(char *dst, const char *src, size_t len)
-{
- return strlncpy(dst, len, src, (size_t) -1);
-}
-
int
request_url_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
strlncat(messages[num_messages].request_url,
sizeof(messages[num_messages].request_url),
buf,
@@ -2037,7 +2041,7 @@ request_url_cb (http_parser *p, const char *buf, size_t len)
int
header_field_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
struct message *m = &messages[num_messages];
if (m->last_header_element != FIELD)
@@ -2056,7 +2060,7 @@ header_field_cb (http_parser *p, const char *buf, size_t len)
int
header_value_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
struct message *m = &messages[num_messages];
strlncat(m->headers[m->num_headers-1][1],
@@ -2085,7 +2089,7 @@ check_body_is_final (const http_parser *p)
int
body_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
strlncat(messages[num_messages].body,
sizeof(messages[num_messages].body),
buf,
@@ -2099,7 +2103,7 @@ body_cb (http_parser *p, const char *buf, size_t len)
int
count_body_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
assert(buf);
messages[num_messages].body_size += len;
check_body_is_final(p);
@@ -2109,7 +2113,8 @@ count_body_cb (http_parser *p, const char *buf, size_t len)
int
message_begin_cb (http_parser *p)
{
- assert(p == parser);
+ assert(p == &parser);
+ assert(!messages[num_messages].message_begin_cb_called);
messages[num_messages].message_begin_cb_called = TRUE;
return 0;
}
@@ -2117,21 +2122,22 @@ message_begin_cb (http_parser *p)
int
headers_complete_cb (http_parser *p)
{
- assert(p == parser);
- messages[num_messages].method = parser->method;
- messages[num_messages].status_code = parser->status_code;
- messages[num_messages].http_major = parser->http_major;
- messages[num_messages].http_minor = parser->http_minor;
+ assert(p == &parser);
+ messages[num_messages].method = parser.method;
+ messages[num_messages].status_code = parser.status_code;
+ messages[num_messages].http_major = parser.http_major;
+ messages[num_messages].http_minor = parser.http_minor;
messages[num_messages].headers_complete_cb_called = TRUE;
- messages[num_messages].should_keep_alive = http_should_keep_alive(parser);
+ messages[num_messages].should_keep_alive = http_should_keep_alive(&parser);
return 0;
}
int
message_complete_cb (http_parser *p)
{
- assert(p == parser);
- if (messages[num_messages].should_keep_alive != http_should_keep_alive(parser))
+ assert(p == &parser);
+ if (messages[num_messages].should_keep_alive !=
+ http_should_keep_alive(&parser))
{
fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same "
"value in both on_message_complete and on_headers_complete "
@@ -2162,7 +2168,7 @@ message_complete_cb (http_parser *p)
int
response_status_cb (http_parser *p, const char *buf, size_t len)
{
- assert(p == parser);
+ assert(p == &parser);
messages[num_messages].status_cb_called = TRUE;
@@ -2176,7 +2182,7 @@ response_status_cb (http_parser *p, const char *buf, size_t len)
int
chunk_header_cb (http_parser *p)
{
- assert(p == parser);
+ assert(p == &parser);
int chunk_idx = messages[num_messages].num_chunks;
messages[num_messages].num_chunks++;
if (chunk_idx < MAX_CHUNKS) {
@@ -2189,7 +2195,7 @@ chunk_header_cb (http_parser *p)
int
chunk_complete_cb (http_parser *p)
{
- assert(p == parser);
+ assert(p == &parser);
/* Here we want to verify that each chunk_header_cb is matched by a
* chunk_complete_cb, so not only should the total number of calls to
@@ -2394,7 +2400,7 @@ connect_headers_complete_cb (http_parser *p)
int
connect_message_complete_cb (http_parser *p)
{
- messages[num_messages].should_keep_alive = http_should_keep_alive(parser);
+ messages[num_messages].should_keep_alive = http_should_keep_alive(&parser);
return message_complete_cb(p);
}
@@ -2467,30 +2473,15 @@ void
parser_init (enum http_parser_type type)
{
num_messages = 0;
-
- assert(parser == NULL);
-
- parser = malloc(sizeof(http_parser));
-
- http_parser_init(parser, type);
-
+ http_parser_init(&parser, type);
memset(&messages, 0, sizeof messages);
-
-}
-
-void
-parser_free ()
-{
- assert(parser);
- free(parser);
- parser = NULL;
}
size_t parse (const char *buf, size_t len)
{
size_t nparsed;
currently_parsing_eof = (len == 0);
- nparsed = http_parser_execute(parser, &settings, buf, len);
+ nparsed = http_parser_execute(&parser, &settings, buf, len);
return nparsed;
}
@@ -2498,7 +2489,7 @@ size_t parse_count_body (const char *buf, size_t len)
{
size_t nparsed;
currently_parsing_eof = (len == 0);
- nparsed = http_parser_execute(parser, &settings_count_body, buf, len);
+ nparsed = http_parser_execute(&parser, &settings_count_body, buf, len);
return nparsed;
}
@@ -2509,7 +2500,7 @@ size_t parse_pause (const char *buf, size_t len)
currently_parsing_eof = (len == 0);
current_pause_parser = &s;
- nparsed = http_parser_execute(parser, current_pause_parser, buf, len);
+ nparsed = http_parser_execute(&parser, current_pause_parser, buf, len);
return nparsed;
}
@@ -2517,7 +2508,7 @@ size_t parse_connect (const char *buf, size_t len)
{
size_t nparsed;
currently_parsing_eof = (len == 0);
- nparsed = http_parser_execute(parser, &settings_connect, buf, len);
+ nparsed = http_parser_execute(&parser, &settings_connect, buf, len);
return nparsed;
}
@@ -2737,7 +2728,7 @@ static void
print_error (const char *raw, size_t error_location)
{
fprintf(stderr, "\n*** %s ***\n\n",
- http_errno_description(HTTP_PARSER_ERRNO(parser)));
+ http_errno_description(HTTP_PARSER_ERRNO(&parser)));
int this_line = 0, char_len = 0;
size_t i, j, len = strlen(raw), error_location_line = 0;
@@ -3280,6 +3271,24 @@ const struct url_test url_tests[] =
,.rv=1 /* s_dead */
}
+, {.name="empty url"
+ ,.url=""
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="NULL url"
+ ,.url=NULL
+ ,.is_connect=0
+ ,.rv=1
+ }
+
+, {.name="full of spaces url"
+ ,.url=" "
+ ,.is_connect=0
+ ,.rv=1
+ }
+
#if HTTP_PARSER_STRICT
, {.name="tab in URL"
@@ -3364,7 +3373,7 @@ test_parse_url (void)
memset(&u, 0, sizeof(u));
rv = http_parser_parse_url(test->url,
- strlen(test->url),
+ test->url ? strlen(test->url) : 0,
test->is_connect,
&u);
@@ -3404,6 +3413,14 @@ test_method_str (void)
assert(0 == strcmp("", http_method_str(1337)));
}
+void
+test_status_str (void)
+{
+ assert(0 == strcmp("OK", http_status_str(HTTP_STATUS_OK)));
+ assert(0 == strcmp("Not Found", http_status_str(HTTP_STATUS_NOT_FOUND)));
+ assert(0 == strcmp("", http_status_str(1337)));
+}
+
void
test_message (const struct message *message)
{
@@ -3418,9 +3435,18 @@ test_message (const struct message *message)
size_t msg2len = raw_len - msg1len;
if (msg1len) {
+ assert(num_messages == 0);
+ messages[0].headers_complete_cb_called = FALSE;
+
read = parse(msg1, msg1len);
- if (message->upgrade && parser->upgrade && num_messages > 0) {
+ if (!messages[0].headers_complete_cb_called && parser.nread != read) {
+ assert(parser.nread == read);
+ print_error(msg1, read);
+ abort();
+ }
+
+ if (message->upgrade && parser.upgrade && num_messages > 0) {
messages[num_messages - 1].upgrade = msg1 + read;
goto test;
}
@@ -3434,7 +3460,7 @@ test_message (const struct message *message)
read = parse(msg2, msg2len);
- if (message->upgrade && parser->upgrade) {
+ if (message->upgrade && parser.upgrade) {
messages[num_messages - 1].upgrade = msg2 + read;
goto test;
}
@@ -3459,8 +3485,6 @@ test_message (const struct message *message)
}
if(!message_eq(0, 0, message)) abort();
-
- parser_free();
}
}
@@ -3496,8 +3520,6 @@ test_message_count_body (const struct message *message)
}
if(!message_eq(0, 0, message)) abort();
-
- parser_free();
}
void
@@ -3510,11 +3532,9 @@ test_simple_type (const char *buf,
enum http_errno err;
parse(buf, strlen(buf));
- err = HTTP_PARSER_ERRNO(parser);
+ err = HTTP_PARSER_ERRNO(&parser);
parse(NULL, 0);
- parser_free();
-
/* In strict mode, allow us to pass with an unexpected HPE_STRICT as
* long as the caller isn't expecting success.
*/
@@ -3854,7 +3874,7 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct
read = parse(total, strlen(total));
- if (parser->upgrade) {
+ if (parser.upgrade) {
upgrade_message_fix(total, read, 3, r1, r2, r3);
goto test;
}
@@ -3881,8 +3901,6 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct
if (!message_eq(0, 0, r1)) abort();
if (message_count > 1 && !message_eq(1, 0, r2)) abort();
if (message_count > 2 && !message_eq(2, 0, r3)) abort();
-
- parser_free();
}
/* SCAN through every possible breaking to make sure the
@@ -3936,9 +3954,17 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
strlncpy(buf3, sizeof(buf1), total+j, buf3_len);
buf3[buf3_len] = 0;
+ assert(num_messages == 0);
+ messages[0].headers_complete_cb_called = FALSE;
+
read = parse(buf1, buf1_len);
- if (parser->upgrade) goto test;
+ if (!messages[0].headers_complete_cb_called && parser.nread != read) {
+ print_error(buf1, read);
+ goto error;
+ }
+
+ if (parser.upgrade) goto test;
if (read != buf1_len) {
print_error(buf1, read);
@@ -3947,7 +3973,7 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
read += parse(buf2, buf2_len);
- if (parser->upgrade) goto test;
+ if (parser.upgrade) goto test;
if (read != buf1_len + buf2_len) {
print_error(buf2, read);
@@ -3956,7 +3982,7 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
read += parse(buf3, buf3_len);
- if (parser->upgrade) goto test;
+ if (parser.upgrade) goto test;
if (read != buf1_len + buf2_len + buf3_len) {
print_error(buf3, read);
@@ -3966,7 +3992,7 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
parse(NULL, 0);
test:
- if (parser->upgrade) {
+ if (parser.upgrade) {
upgrade_message_fix(total, read, 3, r1, r2, r3);
}
@@ -3990,8 +4016,6 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
goto error;
}
-
- parser_free();
}
}
}
@@ -4055,7 +4079,7 @@ test_message_pause (const struct message *msg)
// completion callback.
if (messages[0].message_complete_cb_called &&
msg->upgrade &&
- parser->upgrade) {
+ parser.upgrade) {
messages[0].upgrade = buf + nread;
goto test;
}
@@ -4063,17 +4087,16 @@ test_message_pause (const struct message *msg)
if (nread < buflen) {
// Not much do to if we failed a strict-mode check
- if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) {
- parser_free();
+ if (HTTP_PARSER_ERRNO(&parser) == HPE_STRICT) {
return;
}
- assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED);
+ assert (HTTP_PARSER_ERRNO(&parser) == HPE_PAUSED);
}
buf += nread;
buflen -= nread;
- http_parser_pause(parser, 0);
+ http_parser_pause(&parser, 0);
} while (buflen > 0);
nread = parse_pause(NULL, 0);
@@ -4086,8 +4109,6 @@ test_message_pause (const struct message *msg)
}
if(!message_eq(0, 0, msg)) abort();
-
- parser_free();
}
/* Verify that body and next message won't be parsed in responses to CONNECT */
@@ -4107,17 +4128,12 @@ test_message_connect (const struct message *msg)
}
if(!message_eq(0, 1, msg)) abort();
-
- parser_free();
}
int
main (void)
{
- parser = NULL;
- int i, j, k;
- int request_count;
- int response_count;
+ unsigned i, j, k;
unsigned long version;
unsigned major;
unsigned minor;
@@ -4131,13 +4147,11 @@ main (void)
printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));
- for (request_count = 0; requests[request_count].name; request_count++);
- for (response_count = 0; responses[response_count].name; response_count++);
-
//// API
test_preserve_data();
test_parse_url();
test_method_str();
+ test_status_str();
//// NREAD
test_header_nread_value();
@@ -4168,6 +4182,13 @@ main (void)
test_invalid_header_field_token_error(HTTP_RESPONSE);
test_invalid_header_field_content_error(HTTP_RESPONSE);
+ test_simple_type(
+ "POST / HTTP/1.1\r\n"
+ "Content-Length:\r\n" // empty
+ "\r\n",
+ HPE_INVALID_CONTENT_LENGTH,
+ HTTP_REQUEST);
+
test_simple_type(
"POST / HTTP/1.1\r\n"
"Content-Length: 42 \r\n" // Note the surrounding whitespace.
@@ -4189,6 +4210,20 @@ main (void)
HPE_INVALID_CONTENT_LENGTH,
HTTP_REQUEST);
+ test_simple_type(
+ "POST / HTTP/1.1\r\n"
+ "Content-Length: 42\r\n"
+ " Hello world!\r\n",
+ HPE_INVALID_CONTENT_LENGTH,
+ HTTP_REQUEST);
+
+ test_simple_type(
+ "POST / HTTP/1.1\r\n"
+ "Content-Length: 42\r\n"
+ " \r\n",
+ HPE_OK,
+ HTTP_REQUEST);
+
//// RESPONSES
test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
@@ -4196,24 +4231,25 @@ main (void)
test_simple_type("HTTP/11.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
test_simple_type("HTTP/1.01 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
test_simple_type("HTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
+ test_simple_type("\rHTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE);
- for (i = 0; i < response_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(responses); i++) {
test_message(&responses[i]);
}
- for (i = 0; i < response_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(responses); i++) {
test_message_pause(&responses[i]);
}
- for (i = 0; i < response_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(responses); i++) {
test_message_connect(&responses[i]);
}
- for (i = 0; i < response_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(responses); i++) {
if (!responses[i].should_keep_alive) continue;
- for (j = 0; j < response_count; j++) {
+ for (j = 0; j < ARRAY_SIZE(responses); j++) {
if (!responses[j].should_keep_alive) continue;
- for (k = 0; k < response_count; k++) {
+ for (k = 0; k < ARRAY_SIZE(responses); k++) {
test_multiple3(&responses[i], &responses[j], &responses[k]);
}
}
@@ -4273,11 +4309,16 @@ main (void)
/// REQUESTS
+ test_simple("GET / IHTTP/1.0\r\n\r\n", HPE_INVALID_CONSTANT);
+ test_simple("GET / ICE/1.0\r\n\r\n", HPE_INVALID_CONSTANT);
test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION);
test_simple("GET / HTTP/01.1\r\n\r\n", HPE_INVALID_VERSION);
test_simple("GET / HTTP/11.1\r\n\r\n", HPE_INVALID_VERSION);
test_simple("GET / HTTP/1.01\r\n\r\n", HPE_INVALID_VERSION);
+ test_simple("GET / HTTP/1.0\r\nHello: w\1rld\r\n\r\n", HPE_INVALID_HEADER_TOKEN);
+ test_simple("GET / HTTP/1.0\r\nHello: woooo\2rld\r\n\r\n", HPE_INVALID_HEADER_TOKEN);
+
// Extended characters - see nodejs/test/parallel/test-http-headers-obstext.js
test_simple("GET / HTTP/1.1\r\n"
"Test: Düsseldorf\r\n",
@@ -4360,9 +4401,9 @@ main (void)
"\r\n",
HPE_INVALID_HEADER_TOKEN);
- const char *dumbfuck2 =
+ const char *dumbluck2 =
"GET / HTTP/1.1\r\n"
- "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n"
+ "X-SSL-Nonsense: -----BEGIN CERTIFICATE-----\r\n"
"\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n"
"\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n"
"\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n"
@@ -4395,7 +4436,7 @@ main (void)
"\tRA==\r\n"
"\t-----END CERTIFICATE-----\r\n"
"\r\n";
- test_simple(dumbfuck2, HPE_OK);
+ test_simple(dumbluck2, HPE_OK);
const char *corrupted_connection =
"GET / HTTP/1.1\r\n"
@@ -4429,19 +4470,19 @@ main (void)
/* check to make sure our predefined requests are okay */
- for (i = 0; requests[i].name; i++) {
+ for (i = 0; i < ARRAY_SIZE(requests); i++) {
test_message(&requests[i]);
}
- for (i = 0; i < request_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(requests); i++) {
test_message_pause(&requests[i]);
}
- for (i = 0; i < request_count; i++) {
+ for (i = 0; i < ARRAY_SIZE(requests); i++) {
if (!requests[i].should_keep_alive) continue;
- for (j = 0; j < request_count; j++) {
+ for (j = 0; j < ARRAY_SIZE(requests); j++) {
if (!requests[j].should_keep_alive) continue;
- for (k = 0; k < request_count; k++) {
+ for (k = 0; k < ARRAY_SIZE(requests); k++) {
test_multiple3(&requests[i], &requests[j], &requests[k]);
}
}
@@ -4462,7 +4503,7 @@ main (void)
printf("request scan 3/4 ");
test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END]
, &requests[CHUNKED_W_TRAILING_HEADERS]
- , &requests[CHUNKED_W_BULLSHIT_AFTER_LENGTH]
+ , &requests[CHUNKED_W_NONSENSE_AFTER_LENGTH]
);
printf("request scan 4/4 ");
diff --git a/deps/openssl/openssl_common.gypi b/deps/openssl/openssl_common.gypi
index 67640a6325eb52..93b87064b3fb3e 100644
--- a/deps/openssl/openssl_common.gypi
+++ b/deps/openssl/openssl_common.gypi
@@ -24,7 +24,7 @@
}, 'OS=="win"', {
'defines': [
## default of Win. See INSTALL in openssl repo.
- 'OPENSSLDIR="C:\Program Files\Common Files\SSL"',
+ 'OPENSSLDIR="C:\\\Program\ Files\\\Common\ Files\\\SSL"',
'ENGINESDIR="NUL"',
'OPENSSL_SYS_WIN32', 'WIN32_LEAN_AND_MEAN', 'L_ENDIAN',
'_CRT_SECURE_NO_DEPRECATE', 'UNICODE', '_UNICODE',
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 408cfd6541a339..dcc36e8c17f929 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -411,3 +411,4 @@ Ouyang Yadong
ZYSzys
Carl Lei
Stefan Bender
+nia
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index 7da5e688166c04..2ab6d17edddd72 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -275,6 +275,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
src/unix/linux-syscalls.c
src/unix/procfs-exepath.c
src/unix/pthread-fixes.c
+ src/unix/random-getrandom.c
+ src/unix/random-sysctl-linux.c
src/unix/sysinfo-loadavg.c)
endif()
@@ -320,7 +322,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
src/unix/linux-syscalls.c
src/unix/procfs-exepath.c
src/unix/random-getrandom.c
- src/unix/random-sysctl.c
+ src/unix/random-sysctl-linux.c
src/unix/sysinfo-loadavg.c)
endif()
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index cd4451ae69c0c1..a0509e6e153f65 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,40 @@
+2019.12.05, Version 1.34.0 (Stable), 15ae750151ac9341e5945eb38f8982d59fb99201
+
+Changes since version 1.33.1:
+
+* unix: move random-sysctl to random-sysctl-linux (nia)
+
+* netbsd: use KERN_ARND sysctl to get entropy (nia)
+
+* unix: refactor uv__fs_copyfile() logic (cjihrig)
+
+* build: fix android build, add missing sources (Ben Noordhuis)
+
+* build: fix android build, fix symbol redefinition (Ben Noordhuis)
+
+* build: fix android autotools build (Ben Noordhuis)
+
+* fs: handle non-functional statx system call (Milad Farazmand)
+
+* unix,win: add uv_sleep() (cjihrig)
+
+* doc: add richardlau to maintainers (Richard Lau)
+
+* aix: fix netmask for IPv6 (Richard Lau)
+
+* aix: clean up after errors in uv_interface_addresses() (Richard Lau)
+
+* aix: fix setting of physical addresses (Richard Lau)
+
+* fs: add uv_fs_mkstemp (Saúl Ibarra Corretgé)
+
+* unix: switch uv_sleep() to nanosleep() (Ben Noordhuis)
+
+* unix: retry on EINTR in uv_sleep() (Ben Noordhuis)
+
+* zos: fix nanosleep() emulation (Ben Noordhuis)
+
+
2019.10.20, Version 1.33.1 (Stable), 07ad32138f4d2285ba2226b5e20462b27b091a59
Changes since version 1.33.0:
diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md
index a5a11c8dfff16c..0870b88eb6896b 100644
--- a/deps/uv/MAINTAINERS.md
+++ b/deps/uv/MAINTAINERS.md
@@ -17,6 +17,8 @@ libuv is currently managed by the following individuals:
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
* **John Barboza** ([@jbarz](https://github.com/jbarz))
+* **Richard Lau** ([@richardlau](https://github.com/richardlau))
+ - GPG key: C82F A3AE 1CBE DC6B E46B 9360 C43C EC45 C17A B93C (pubkey-richardlau)
* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index ce4ca274b217ee..088b4bbd76f375 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -387,7 +387,14 @@ endif
if ANDROID
uvinclude_HEADERS += include/uv/android-ifaddrs.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
- src/unix/pthread-fixes.c
+ src/unix/linux-core.c \
+ src/unix/linux-inotify.c \
+ src/unix/linux-syscalls.c \
+ src/unix/procfs-exepath.c \
+ src/unix/pthread-fixes.c \
+ src/unix/random-getrandom.c \
+ src/unix/random-sysctl-linux.c \
+ src/unix/sysinfo-loadavg.c
endif
if CYGWIN
@@ -467,7 +474,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/procfs-exepath.c \
src/unix/proctitle.c \
src/unix/random-getrandom.c \
- src/unix/random-sysctl.c \
+ src/unix/random-sysctl-linux.c \
src/unix/sysinfo-loadavg.c
test_run_tests_LDFLAGS += -lutil
endif
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 07ad0cde81a656..6ea6b6a06cd1db 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.33.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.34.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])
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index dc16ff08e65a93..28356c2d442e43 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -99,7 +99,8 @@ Data types
UV_FS_LCHOWN,
UV_FS_OPENDIR,
UV_FS_READDIR,
- UV_FS_CLOSEDIR
+ UV_FS_CLOSEDIR,
+ UV_FS_MKSTEMP
} uv_fs_type;
.. c:type:: uv_statfs_t
@@ -245,10 +246,14 @@ API
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
- Equivalent to :man:`mkdtemp(3)`.
+ Equivalent to :man:`mkdtemp(3)`. The result can be found as a null terminated string at `req->path`.
- .. note::
- The result can be found as a null terminated string at `req->path`.
+.. c:function:: int uv_fs_mkstemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
+
+ Equivalent to :man:`mkstemp(3)`. The created file path can be found as a null terminated string at `req->path`.
+ The file descriptor can be found as an integer at `req->result`.
+
+ .. versionadded:: 1.34.0
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 8e167e3ec4ec1d..3264973bcce151 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -679,6 +679,7 @@ API
:man:`sysctl(2)`.
- FreeBSD: `getrandom(2) _`,
or `/dev/urandom` after reading from `/dev/random` once.
+ - NetBSD: `KERN_ARND` `sysctl(3) _`
- macOS, OpenBSD: `getentropy(2) _`
if available, or `/dev/urandom` after reading from `/dev/random` once.
- AIX: `/dev/random`.
@@ -693,3 +694,9 @@ API
are not used and can be set to `NULL`.
.. versionadded:: 1.33.0
+
+.. c:function:: void uv_sleep(unsigned int msec)
+
+ Causes the calling thread to sleep for `msec` milliseconds.
+
+ .. versionadded:: 1.34.0
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 0e8132e4384be0..626cebabd8c9ea 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -1258,7 +1258,8 @@ typedef enum {
UV_FS_OPENDIR,
UV_FS_READDIR,
UV_FS_CLOSEDIR,
- UV_FS_STATFS
+ UV_FS_STATFS,
+ UV_FS_MKSTEMP
} uv_fs_type;
struct uv_dir_s {
@@ -1349,6 +1350,10 @@ UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop,
uv_fs_t* req,
const char* tpl,
uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb);
UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
@@ -1641,6 +1646,7 @@ UV_EXTERN uint64_t uv_get_total_memory(void);
UV_EXTERN uint64_t uv_get_constrained_memory(void);
UV_EXTERN uint64_t uv_hrtime(void);
+UV_EXTERN void uv_sleep(unsigned int msec);
UV_EXTERN void uv_disable_stdio_inheritance(void);
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index ca94be6dd4fba6..8017302600d9f3 100644
--- a/deps/uv/include/uv/version.h
+++ b/deps/uv/include/uv/version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 33
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 34
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/random.c b/deps/uv/src/random.c
index 8c4fe32013dc9a..491bf703309955 100644
--- a/deps/uv/src/random.c
+++ b/deps/uv/src/random.c
@@ -40,6 +40,8 @@ static int uv__random(void* buf, size_t buflen) {
rc = uv__random_getentropy(buf, buflen);
if (rc == UV_ENOSYS)
rc = uv__random_devurandom(buf, buflen);
+#elif defined(__NetBSD__)
+ rc = uv__random_sysctl(buf, buflen);
#elif defined(__FreeBSD__) || defined(__linux__)
rc = uv__random_getrandom(buf, buflen);
if (rc == UV_ENOSYS)
diff --git a/deps/uv/src/unix/aix-common.c b/deps/uv/src/unix/aix-common.c
index b9d313c0c5d7cb..e96e34c46373bb 100644
--- a/deps/uv/src/unix/aix-common.c
+++ b/deps/uv/src/unix/aix-common.c
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
@@ -158,28 +159,42 @@ int uv_exepath(char* buffer, size_t* size) {
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
- int sockfd, inet6, size = 1;
+ int sockfd, sock6fd, inet6, i, r, size = 1;
struct ifconf ifc;
struct ifreq *ifr, *p, flg;
+ struct in6_ifreq if6;
struct sockaddr_dl* sa_addr;
+ ifc.ifc_req = NULL;
+ sock6fd = -1;
+ r = 0;
*count = 0;
*addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
+ }
+
+ if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
+ r = UV__ERR(errno);
+ goto cleanup;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
+ if (ifc.ifc_req == NULL) {
+ r = UV_ENOMEM;
+ goto cleanup;
+ }
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
@@ -197,8 +212,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -207,16 +222,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
- if (*count == 0) {
- uv__close(sockfd);
- return 0;
- }
+ if (*count == 0)
+ goto cleanup;
/* Alloc the return interface structs */
- *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
+ *addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
- uv__close(sockfd);
- return UV_ENOMEM;
+ r = UV_ENOMEM;
+ goto cleanup;
}
address = *addresses;
@@ -233,10 +246,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
inet6 = (p->ifr_addr.sa_family == AF_INET6);
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
- if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- uv__close(sockfd);
- return UV_ENOSYS;
- }
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
+ goto syserror;
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
@@ -250,28 +261,67 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
else
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
- sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
- memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-
- if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
- uv__close(sockfd);
- return UV_ENOSYS;
- }
-
- if (inet6)
- address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr);
- else
+ if (inet6) {
+ memset(&if6, 0, sizeof(if6));
+ r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
+ if (r == UV_E2BIG)
+ goto cleanup;
+ r = 0;
+ memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
+ if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
+ goto syserror;
+ address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
+ /* Explicitly set family as the ioctl call appears to return it as 0. */
+ address->netmask.netmask6.sin6_family = AF_INET6;
+ } else {
+ if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
+ goto syserror;
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
+ /* Explicitly set family as the ioctl call appears to return it as 0. */
+ address->netmask.netmask4.sin_family = AF_INET;
+ }
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
address++;
}
+ /* Fill in physical addresses. */
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (p->ifr_addr.sa_family != AF_LINK)
+ continue;
+
+ address = *addresses;
+ for (i = 0; i < *count; i++) {
+ if (strcmp(address->name, p->ifr_name) == 0) {
+ sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
#undef ADDR_SIZE
+ goto cleanup;
- uv__close(sockfd);
- return 0;
+syserror:
+ uv_free_interface_addresses(*addresses, *count);
+ *addresses = NULL;
+ *count = 0;
+ r = UV_ENOSYS;
+
+cleanup:
+ if (sockfd != -1)
+ uv__close(sockfd);
+ if (sock6fd != -1)
+ uv__close(sock6fd);
+ uv__free(ifc.ifc_req);
+ return r;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index ffce948c957403..04999dce36d193 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -1555,3 +1555,17 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
tv->tv_usec = (int32_t) time.tv_usec;
return 0;
}
+
+void uv_sleep(unsigned int msec) {
+ struct timespec timeout;
+ int rc;
+
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
+
+ do
+ rc = nanosleep(&timeout, &timeout);
+ while (rc == -1 && errno == EINTR);
+
+ assert(rc == 0);
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index b37cfbbc7a04ee..be256bfca6c58a 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -30,6 +30,7 @@
#include "internal.h"
#include
+#include
#include
#include
#include
@@ -258,6 +259,80 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
}
+static int uv__fs_mkstemp(uv_fs_t* req) {
+ int r;
+#ifdef O_CLOEXEC
+ int (*mkostemp_function)(char*, int);
+ static int no_cloexec_support;
+#endif
+ static const char pattern[] = "XXXXXX";
+ static const size_t pattern_size = sizeof(pattern) - 1;
+ char* path;
+ size_t path_length;
+
+ path = (char*) req->path;
+ path_length = strlen(path);
+
+ /* EINVAL can be returned for 2 reasons:
+ 1. The template's last 6 characters were not XXXXXX
+ 2. open() didn't support O_CLOEXEC
+ We want to avoid going to the fallback path in case
+ of 1, so it's manually checked before. */
+ if (path_length < pattern_size ||
+ strcmp(path + path_length - pattern_size, pattern)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+#ifdef O_CLOEXEC
+ if (no_cloexec_support == 0) {
+ *(int**)(&mkostemp_function) = dlsym(RTLD_DEFAULT, "mkostemp");
+
+ /* We don't care about errors, but we do want to clean them up.
+ If there has been no error, then dlerror() will just return
+ NULL. */
+ dlerror();
+
+ if (mkostemp_function != NULL) {
+ r = mkostemp_function(path, O_CLOEXEC);
+
+ if (r >= 0)
+ return r;
+
+ /* If mkostemp() returns EINVAL, it means the kernel doesn't
+ support O_CLOEXEC, so we just fallback to mkstemp() below. */
+ if (errno != EINVAL)
+ return r;
+
+ /* We set the static variable so that next calls don't even
+ try to use mkostemp. */
+ no_cloexec_support = 1;
+ }
+ }
+#endif /* O_CLOEXEC */
+
+ if (req->cb != NULL)
+ uv_rwlock_rdlock(&req->loop->cloexec_lock);
+
+ r = mkstemp(path);
+
+ /* In case of failure `uv__cloexec` will leave error in `errno`,
+ * so it is enough to just set `r` to `-1`.
+ */
+ if (r >= 0 && uv__cloexec(r, 1) != 0) {
+ r = uv__close(r);
+ if (r != 0)
+ abort();
+ r = -1;
+ }
+
+ if (req->cb != NULL)
+ uv_rwlock_rdunlock(&req->loop->cloexec_lock);
+
+ return r;
+}
+
+
static ssize_t uv__fs_open(uv_fs_t* req) {
#ifdef O_CLOEXEC
return open(req->path, req->flags | O_CLOEXEC, req->mode);
@@ -999,6 +1074,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
int err;
size_t bytes_to_send;
int64_t in_offset;
+ ssize_t bytes_written;
dstfd = -1;
err = 0;
@@ -1076,18 +1152,17 @@ 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) {
- err = uv_fs_sendfile(NULL,
- &fs_req,
- dstfd,
- srcfd,
- in_offset,
- bytes_to_send,
- NULL);
+ uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_to_send, NULL);
+ bytes_written = fs_req.result;
uv_fs_req_cleanup(&fs_req);
- if (err < 0)
+
+ if (bytes_written < 0) {
+ err = bytes_written;
break;
- bytes_to_send -= fs_req.result;
- in_offset += fs_req.result;
+ }
+
+ bytes_to_send -= bytes_written;
+ in_offset += bytes_written;
}
out:
@@ -1234,13 +1309,22 @@ static int uv__fs_statx(int fd,
rc = uv__statx(dirfd, path, flags, mode, &statxbuf);
- if (rc == -1) {
+ switch (rc) {
+ case 0:
+ break;
+ case -1:
/* EPERM happens when a seccomp filter rejects the system call.
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
*/
if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
return -1;
-
+ /* Fall through. */
+ default:
+ /* Normally on success, zero is returned and On error, -1 is returned.
+ * Observed on S390 RHEL running in a docker container with statx not
+ * implemented, rc might return 1 with 0 set as the error code in which
+ * case we return ENOSYS.
+ */
no_statx = 1;
return UV_ENOSYS;
}
@@ -1415,6 +1499,7 @@ static void uv__fs_work(struct uv__work* w) {
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
+ X(MKSTEMP, uv__fs_mkstemp(req));
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req));
@@ -1639,6 +1724,18 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
}
+int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
+ INIT(MKSTEMP);
+ req->path = uv__strdup(tpl);
+ if (req->path == NULL)
+ return UV_ENOMEM;
+ POST;
+}
+
+
int uv_fs_open(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
@@ -1857,10 +1954,12 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
/* Only necessary for asychronous requests, i.e., requests with a callback.
* Synchronous ones don't copy their arguments and have req->path and
- * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
- * exception to the rule, it always allocates memory.
+ * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP and
+ * UV_FS_MKSTEMP are the exception to the rule, they always allocate memory.
*/
- if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
+ if (req->path != NULL &&
+ (req->cb != NULL ||
+ req->fs_type == UV_FS_MKDTEMP || req->fs_type == UV_FS_MKSTEMP))
uv__free((void*) req->path); /* Memory is shared with req->new_path. */
req->path = NULL;
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index cfe2c6a49dc3c7..690bd79ef91a36 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -234,3 +234,26 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv__free(cp_times);
return 0;
}
+
+int uv__random_sysctl(void* buf, size_t len) {
+ static int name[] = {CTL_KERN, KERN_ARND};
+ size_t count, req;
+ unsigned char* p;
+
+ p = buf;
+ while (len) {
+ req = len < 32 ? len : 32;
+ count = req;
+
+ if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1)
+ return UV__ERR(errno);
+
+ if (count != req)
+ return UV_EIO; /* Can't happen. */
+
+ p += count;
+ len -= count;
+ }
+
+ return 0;
+}
diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c
index 1040d66979da04..d9abdebaeeda59 100644
--- a/deps/uv/src/unix/os390-syscalls.c
+++ b/deps/uv/src/unix/os390-syscalls.c
@@ -23,11 +23,11 @@
#include "os390-syscalls.h"
#include
#include
-#include
#include
#include
#include
+#define CW_INTRPT 1
#define CW_CONDVAR 32
#pragma linkage(BPX4CTW, OS)
@@ -350,27 +350,34 @@ int nanosleep(const struct timespec* req, struct timespec* rem) {
unsigned secrem;
unsigned nanorem;
int rv;
- int rc;
+ int err;
int rsn;
nano = (int)req->tv_nsec;
seconds = req->tv_sec;
- events = CW_CONDVAR;
+ events = CW_CONDVAR | CW_INTRPT;
+ secrem = 0;
+ nanorem = 0;
#if defined(_LP64)
- BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+ BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
#else
- BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+ BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
#endif
- assert(rv == -1 && errno == EAGAIN);
+ /* Don't clobber errno unless BPX1CTW/BPX4CTW errored.
+ * Don't leak EAGAIN, that just means the timeout expired.
+ */
+ if (rv == -1)
+ if (err != EAGAIN)
+ errno = err;
- if(rem != NULL) {
+ if (rem != NULL && (rv == 0 || err == EINTR || err == EAGAIN)) {
rem->tv_nsec = nanorem;
rem->tv_sec = secrem;
}
- return 0;
+ return rv;
}
diff --git a/deps/uv/src/unix/random-devurandom.c b/deps/uv/src/unix/random-devurandom.c
index bfc40d20f88cb7..9aa762e372ea3f 100644
--- a/deps/uv/src/unix/random-devurandom.c
+++ b/deps/uv/src/unix/random-devurandom.c
@@ -74,10 +74,10 @@ int uv__random_readpath(const char* path, void* buf, size_t buflen) {
static void uv__random_devurandom_init(void) {
char c;
- /* Linux's and NetBSD's random(4) man page suggests applications should read
- * at least once from /dev/random before switching to /dev/urandom in order
- * to seed the system RNG. Reads from /dev/random can of course block
- * indefinitely until entropy is available but that's the point.
+ /* Linux's random(4) man page suggests applications should read at least
+ * once from /dev/random before switching to /dev/urandom in order to seed
+ * the system RNG. Reads from /dev/random can of course block indefinitely
+ * until entropy is available but that's the point.
*/
status = uv__random_readpath("/dev/random", &c, 1);
}
diff --git a/deps/uv/src/unix/random-sysctl.c b/deps/uv/src/unix/random-sysctl-linux.c
similarity index 97%
rename from deps/uv/src/unix/random-sysctl.c
rename to deps/uv/src/unix/random-sysctl-linux.c
index fb182ded09296b..66ba8d74ec22b7 100644
--- a/deps/uv/src/unix/random-sysctl.c
+++ b/deps/uv/src/unix/random-sysctl-linux.c
@@ -40,7 +40,6 @@ struct uv__sysctl_args {
};
-/* TODO(bnoordhuis) Use {CTL_KERN, KERN_ARND} on FreeBSD (and NetBSD?) */
int uv__random_sysctl(void* buf, size_t buflen) {
static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/};
struct uv__sysctl_args args;
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 3ab486080cdfa7..8502b072021a9e 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -1195,9 +1195,10 @@ void fs__mkdir(uv_fs_t* req) {
}
}
+typedef int (*uv__fs_mktemp_func)(uv_fs_t* req);
/* OpenBSD original: lib/libc/stdio/mktemp.c */
-void fs__mkdtemp(uv_fs_t* req) {
+void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
static const WCHAR *tempchars =
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static const size_t num_chars = 62;
@@ -1227,13 +1228,11 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars;
}
- if (_wmkdir(req->file.pathw) == 0) {
- len = strlen(req->path);
- wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
- SET_REQ_RESULT(req, 0);
- break;
- } else if (errno != EEXIST) {
- SET_REQ_RESULT(req, -1);
+ if (func(req)) {
+ if (req->result >= 0) {
+ len = strlen(req->path);
+ wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
+ }
break;
}
} while (--tries);
@@ -1244,6 +1243,77 @@ void fs__mkdtemp(uv_fs_t* req) {
}
+static int fs__mkdtemp_func(uv_fs_t* req) {
+ if (_wmkdir(req->file.pathw) == 0) {
+ SET_REQ_RESULT(req, 0);
+ return 1;
+ } else if (errno != EEXIST) {
+ SET_REQ_RESULT(req, -1);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void fs__mkdtemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkdtemp_func);
+}
+
+
+static int fs__mkstemp_func(uv_fs_t* req) {
+ HANDLE file;
+ int fd;
+
+ file = CreateFileW(req->file.pathw,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (file == INVALID_HANDLE_VALUE) {
+ DWORD error;
+ error = GetLastError();
+
+ /* If the file exists, the main fs__mktemp() function
+ will retry. If it's another error, we want to stop. */
+ if (error != ERROR_FILE_EXISTS) {
+ SET_REQ_WIN32_ERROR(req, error);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ fd = _open_osfhandle((intptr_t) file, 0);
+ if (fd < 0) {
+ /* The only known failure mode for _open_osfhandle() is EMFILE, in which
+ * case GetLastError() will return zero. However we'll try to handle other
+ * errors as well, should they ever occur.
+ */
+ if (errno == EMFILE)
+ SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
+ else if (GetLastError() != ERROR_SUCCESS)
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ else
+ SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+ CloseHandle(file);
+ return 1;
+ }
+
+ SET_REQ_RESULT(req, fd);
+
+ return 1;
+}
+
+
+void fs__mkstemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkstemp_func);
+}
+
+
void fs__scandir(uv_fs_t* req) {
static const size_t dirents_initial_size = 32;
@@ -2609,6 +2679,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(RMDIR, rmdir)
XX(MKDIR, mkdir)
XX(MKDTEMP, mkdtemp)
+ XX(MKSTEMP, mkstemp)
XX(RENAME, rename)
XX(SCANDIR, scandir)
XX(READDIR, readdir)
@@ -2785,8 +2856,10 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
}
-int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
- uv_fs_cb cb) {
+int uv_fs_mkdtemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
int err;
INIT(UV_FS_MKDTEMP);
@@ -2798,6 +2871,21 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
}
+int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_MKSTEMP);
+ err = fs__capture_path(req, tpl, NULL, TRUE);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ POST;
+}
+
+
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 4bbeb3154123dd..4de638f5971c35 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -1873,3 +1873,7 @@ int uv__random_rtlgenrandom(void* buf, size_t buflen) {
return 0;
}
+
+void uv_sleep(unsigned int msec) {
+ Sleep(msec);
+}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index 432cf33d482cd9..716c15ff088fa9 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -448,17 +448,3 @@ void rewind_cursor(void) {
fprintf(stderr, "\033[2K\r");
#endif
}
-
-
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec) {
- int sec;
- int usec;
-
- sec = msec / 1000;
- usec = (msec % 1000) * 1000;
- if (sec > 0)
- sleep(sec);
- if (usec > 0)
- usleep(usec);
-}
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 6bb41a5d0629c8..4167a386921ec7 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -355,9 +355,3 @@ void rewind_cursor() {
fprintf(stderr, "\n");
}
}
-
-
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec) {
- Sleep(msec);
-}
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index e763f89f09dcd1..bc7b53369b538a 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -131,9 +131,6 @@ typedef enum {
int run_helper_##name(void); \
int run_helper_##name(void)
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec);
-
/* Format big numbers nicely. WARNING: leaks memory. */
const char* fmt(double d);
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 9326c6bc2753f0..ded1eec8dc632c 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -73,6 +73,7 @@ static int write_cb_count;
static int unlink_cb_count;
static int mkdir_cb_count;
static int mkdtemp_cb_count;
+static int mkstemp_cb_count;
static int rmdir_cb_count;
static int scandir_cb_count;
static int stat_cb_count;
@@ -107,6 +108,9 @@ static uv_fs_t close_req;
static uv_fs_t mkdir_req;
static uv_fs_t mkdtemp_req1;
static uv_fs_t mkdtemp_req2;
+static uv_fs_t mkstemp_req1;
+static uv_fs_t mkstemp_req2;
+static uv_fs_t mkstemp_req3;
static uv_fs_t rmdir_req;
static uv_fs_t scandir_req;
static uv_fs_t stat_req;
@@ -538,6 +542,32 @@ static void mkdtemp_cb(uv_fs_t* req) {
}
+static void check_mkstemp_result(uv_fs_t* req) {
+ int r;
+
+ ASSERT(req->fs_type == UV_FS_MKSTEMP);
+ ASSERT(req->result >= 0);
+ ASSERT(req->path);
+ ASSERT(strlen(req->path) == 16);
+ ASSERT(memcmp(req->path, "test_file_", 10) == 0);
+ ASSERT(memcmp(req->path + 10, "XXXXXX", 6) != 0);
+ check_permission(req->path, 0600);
+
+ /* Check if req->path is actually a file */
+ r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
+ ASSERT(r == 0);
+ ASSERT(stat_req.statbuf.st_mode & S_IFREG);
+ uv_fs_req_cleanup(&stat_req);
+}
+
+
+static void mkstemp_cb(uv_fs_t* req) {
+ ASSERT(req == &mkstemp_req1);
+ check_mkstemp_result(req);
+ mkstemp_cb_count++;
+}
+
+
static void rmdir_cb(uv_fs_t* req) {
ASSERT(req == &rmdir_req);
ASSERT(req->fs_type == UV_FS_RMDIR);
@@ -1208,6 +1238,69 @@ TEST_IMPL(fs_mkdtemp) {
}
+TEST_IMPL(fs_mkstemp) {
+ int r;
+ int fd;
+ const char path_template[] = "test_file_XXXXXX";
+ uv_fs_t req;
+
+ loop = uv_default_loop();
+
+ r = uv_fs_mkstemp(loop, &mkstemp_req1, path_template, mkstemp_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(mkstemp_cb_count == 1);
+
+ /* sync mkstemp */
+ r = uv_fs_mkstemp(NULL, &mkstemp_req2, path_template, NULL);
+ ASSERT(r >= 0);
+ check_mkstemp_result(&mkstemp_req2);
+
+ /* mkstemp return different values on subsequent calls */
+ ASSERT(strcmp(mkstemp_req1.path, mkstemp_req2.path) != 0);
+
+ /* invalid template returns EINVAL */
+ ASSERT(uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL) == UV_EINVAL);
+
+ /* We can write to the opened file */
+ iov = uv_buf_init(test_buf, sizeof(test_buf));
+ r = uv_fs_write(NULL, &req, mkstemp_req1.result, &iov, 1, -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ /* Cleanup */
+ uv_fs_close(NULL, &req, mkstemp_req1.result, NULL);
+ uv_fs_req_cleanup(&req);
+ uv_fs_close(NULL, &req, mkstemp_req2.result, NULL);
+ uv_fs_req_cleanup(&req);
+
+ fd = uv_fs_open(NULL, &req, mkstemp_req1.path , O_RDONLY, 0, NULL);
+ ASSERT(fd >= 0);
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ iov = uv_buf_init(buf, sizeof(buf));
+ r = uv_fs_read(NULL, &req, fd, &iov, 1, -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+ uv_fs_req_cleanup(&req);
+
+ uv_fs_close(NULL, &req, fd, NULL);
+ uv_fs_req_cleanup(&req);
+
+ unlink(mkstemp_req1.path);
+ unlink(mkstemp_req2.path);
+ uv_fs_req_cleanup(&mkstemp_req1);
+ uv_fs_req_cleanup(&mkstemp_req2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(fs_fstat) {
int r;
uv_fs_t req;
@@ -3784,6 +3877,9 @@ TEST_IMPL(fs_null_req) {
r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL);
ASSERT(r == UV_EINVAL);
+ r = uv_fs_mkstemp(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
r = uv_fs_rmdir(NULL, NULL, NULL, NULL);
ASSERT(r == UV_EINVAL);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index ad94c52d0c5866..a6cfc6bb9284bd 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -310,6 +310,7 @@ TEST_DECLARE (fs_async_dir)
TEST_DECLARE (fs_async_sendfile)
TEST_DECLARE (fs_async_sendfile_nodata)
TEST_DECLARE (fs_mkdtemp)
+TEST_DECLARE (fs_mkstemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
@@ -920,6 +921,7 @@ TASK_LIST_START
TEST_ENTRY (fs_async_sendfile)
TEST_ENTRY (fs_async_sendfile_nodata)
TEST_ENTRY (fs_mkdtemp)
+ TEST_ENTRY (fs_mkstemp)
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 051bdc937c9fd3..c4564c04086bc0 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -245,7 +245,7 @@
'src/unix/linux-syscalls.h',
'src/unix/procfs-exepath.c',
'src/unix/random-getrandom.c',
- 'src/unix/random-sysctl.c',
+ 'src/unix/random-sysctl-linux.c',
'src/unix/sysinfo-loadavg.c',
],
'link_settings': {
@@ -261,8 +261,9 @@
'src/unix/pthread-fixes.c',
'src/unix/android-ifaddrs.c',
'src/unix/procfs-exepath.c',
+ 'src/unix/random-getrandom.c',
+ 'src/unix/random-sysctl-linux.c',
'src/unix/sysinfo-loadavg.c',
- 'src/unix/sysinfo-memory.c',
],
'link_settings': {
'libraries': [ '-ldl' ],
diff --git a/deps/uvwasi/LICENSE b/deps/uvwasi/LICENSE
new file mode 100644
index 00000000000000..dfb8546af52b03
--- /dev/null
+++ b/deps/uvwasi/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Colin Ihrig and Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/deps/uvwasi/include/clocks.h b/deps/uvwasi/include/clocks.h
new file mode 100644
index 00000000000000..7437d03df6bfa7
--- /dev/null
+++ b/deps/uvwasi/include/clocks.h
@@ -0,0 +1,13 @@
+#ifndef __UVWASI_CLOCKS_H__
+#define __UVWASI_CLOCKS_H__
+
+#include "wasi_types.h"
+
+uvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time);
+uvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time);
+uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time);
+
+uvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time);
+uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time);
+
+#endif /* __UVWASI_CLOCKS_H__ */
diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/include/fd_table.h
new file mode 100644
index 00000000000000..639ff9abc8d34f
--- /dev/null
+++ b/deps/uvwasi/include/fd_table.h
@@ -0,0 +1,57 @@
+#ifndef __UVWASI_FD_TABLE_H__
+#define __UVWASI_FD_TABLE_H__
+
+#include
+#include "uv.h"
+#include "wasi_types.h"
+#include "uv_mapping.h"
+
+struct uvwasi_s;
+
+struct uvwasi_fd_wrap_t {
+ uvwasi_fd_t id;
+ uv_file fd;
+ char* path;
+ char* real_path;
+ uvwasi_filetype_t type;
+ uvwasi_rights_t rights_base;
+ uvwasi_rights_t rights_inheriting;
+ int preopen;
+ uv_mutex_t mutex;
+};
+
+struct uvwasi_fd_table_t {
+ struct uvwasi_fd_wrap_t** fds;
+ uint32_t size;
+ uint32_t used;
+ uv_rwlock_t rwlock;
+};
+
+uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ uint32_t init_size);
+void uvwasi_fd_table_free(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table);
+uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uv_file fd,
+ const char* path,
+ const char* real_path);
+uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uv_file fd,
+ const int flags,
+ const char* path,
+ uvwasi_rights_t rights_base,
+ uvwasi_rights_t rights_inheriting,
+ struct uvwasi_fd_wrap_t* wrap);
+uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
+ const uvwasi_fd_t id,
+ struct uvwasi_fd_wrap_t** wrap,
+ uvwasi_rights_t rights_base,
+ uvwasi_rights_t rights_inheriting);
+uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uvwasi_fd_t id);
+
+#endif /* __UVWASI_FD_TABLE_H__ */
diff --git a/deps/uvwasi/include/uv_mapping.h b/deps/uvwasi/include/uv_mapping.h
new file mode 100644
index 00000000000000..d835ca507a4856
--- /dev/null
+++ b/deps/uvwasi/include/uv_mapping.h
@@ -0,0 +1,15 @@
+#ifndef __UVWASI_UV_MAPPING_H__
+#define __UVWASI_UV_MAPPING_H__
+
+#include "uv.h"
+#include "wasi_types.h"
+
+#define NANOS_PER_SEC 1000000000
+
+uvwasi_errno_t uvwasi__translate_uv_error(int err);
+int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig);
+uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts);
+uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat);
+void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs);
+
+#endif /* __UVWASI_UV_MAPPING_H__ */
diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h
new file mode 100644
index 00000000000000..2fbcbc583dcbfb
--- /dev/null
+++ b/deps/uvwasi/include/uvwasi.h
@@ -0,0 +1,267 @@
+#ifndef __UVWASI_H__
+#define __UVWASI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "wasi_types.h"
+#include "uv_mapping.h"
+#include "fd_table.h"
+
+#define UVWASI_VERSION_MAJOR 0
+#define UVWASI_VERSION_MINOR 0
+#define UVWASI_VERSION_PATCH 3
+#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
+ (UVWASI_VERSION_MINOR << 8) | \
+ (UVWASI_VERSION_PATCH))
+#define UVWASI_STRINGIFY(v) UVWASI_STRINGIFY_HELPER(v)
+#define UVWASI_STRINGIFY_HELPER(v) #v
+#define UVWASI_VERSION_STRING UVWASI_STRINGIFY(UVWASI_VERSION_MAJOR) "." \
+ UVWASI_STRINGIFY(UVWASI_VERSION_MINOR) "." \
+ UVWASI_STRINGIFY(UVWASI_VERSION_PATCH)
+#define UVWASI_VERSION_WASI "snapshot_1"
+
+typedef void* (*uvwasi_malloc)(size_t size, void* mem_user_data);
+typedef void (*uvwasi_free)(void* ptr, void* mem_user_data);
+typedef void* (*uvwasi_calloc)(size_t nmemb, size_t size, void* mem_user_data);
+typedef void* (*uvwasi_realloc)(void* ptr, size_t size, void* mem_user_data);
+
+typedef struct uvwasi_mem_s {
+ void* mem_user_data;
+ uvwasi_malloc malloc;
+ uvwasi_free free;
+ uvwasi_calloc calloc;
+ uvwasi_realloc realloc;
+} uvwasi_mem_t;
+
+typedef struct uvwasi_s {
+ struct uvwasi_fd_table_t fds;
+ size_t argc;
+ char** argv;
+ char* argv_buf;
+ size_t argv_buf_size;
+ size_t envc;
+ char** env;
+ char* env_buf;
+ size_t env_buf_size;
+ const uvwasi_mem_t* allocator;
+} uvwasi_t;
+
+typedef struct uvwasi_preopen_s {
+ char* mapped_path;
+ char* real_path;
+} uvwasi_preopen_t;
+
+typedef struct uvwasi_options_s {
+ size_t fd_table_size;
+ size_t preopenc;
+ uvwasi_preopen_t* preopens;
+ size_t argc;
+ char** argv;
+ char** envp;
+ const uvwasi_mem_t* allocator;
+} uvwasi_options_t;
+
+// Embedder API.
+uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
+void uvwasi_destroy(uvwasi_t* uvwasi);
+uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
+ const uvwasi_fd_t fd,
+ uv_file 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_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
+ uvwasi_clockid_t clock_id,
+ uvwasi_timestamp_t* resolution);
+uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
+ uvwasi_clockid_t clock_id,
+ uvwasi_timestamp_t precision,
+ uvwasi_timestamp_t* time);
+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_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t offset,
+ uvwasi_filesize_t len,
+ uvwasi_advice_t advice);
+uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t offset,
+ uvwasi_filesize_t len);
+uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd);
+uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
+uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_fdstat_t* buf);
+uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_fdflags_t flags);
+uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_rights_t fs_rights_base,
+ uvwasi_rights_t fs_rights_inheriting
+ );
+uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filestat_t* buf);
+uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t st_size);
+uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_timestamp_t st_atim,
+ uvwasi_timestamp_t st_mtim,
+ uvwasi_fstflags_t fst_flags);
+uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const uvwasi_iovec_t* iovs,
+ size_t iovs_len,
+ uvwasi_filesize_t offset,
+ 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_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const uvwasi_ciovec_t* iovs,
+ size_t iovs_len,
+ uvwasi_filesize_t offset,
+ 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_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ void* buf,
+ size_t buf_len,
+ uvwasi_dircookie_t cookie,
+ size_t* bufused);
+uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
+ uvwasi_fd_t from,
+ uvwasi_fd_t to);
+uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filedelta_t offset,
+ uvwasi_whence_t whence,
+ uvwasi_filesize_t* newoffset);
+uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd);
+uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t* offset);
+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_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const char* path,
+ 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_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_timestamp_t st_atim,
+ uvwasi_timestamp_t st_mtim,
+ uvwasi_fstflags_t fst_flags);
+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_fd_t new_fd,
+ const char* new_path,
+ 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_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);
+uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const char* path,
+ size_t path_len,
+ char* buf,
+ size_t buf_len,
+ 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_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
+ uvwasi_fd_t old_fd,
+ const char* old_path,
+ size_t old_path_len,
+ uvwasi_fd_t new_fd,
+ const char* new_path,
+ size_t new_path_len);
+uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
+ const char* old_path,
+ size_t old_path_len,
+ uvwasi_fd_t fd,
+ const char* new_path,
+ 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_errno_t uvwasi_poll_oneoff(uvwasi_t* uvwasi,
+ const uvwasi_subscription_t* in,
+ uvwasi_event_t* out,
+ size_t nsubscriptions,
+ 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_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_riflags_t ri_flags,
+ 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_siflags_t si_flags,
+ size_t* so_datalen);
+uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
+ uvwasi_fd_t sock,
+ uvwasi_sdflags_t how);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UVWASI_H__ */
diff --git a/deps/uvwasi/include/wasi_types.h b/deps/uvwasi/include/wasi_types.h
new file mode 100644
index 00000000000000..ec1013663f6a76
--- /dev/null
+++ b/deps/uvwasi/include/wasi_types.h
@@ -0,0 +1,322 @@
+#ifndef __UVWASI_WASI_TYPES_H__
+#define __UVWASI_WASI_TYPES_H__
+
+#include
+#include
+
+/* API: https://github.com/WebAssembly/WASI/blob/master/phases/unstable/docs/wasi_unstable_preview0.md */
+
+typedef uint8_t uvwasi_advice_t;
+#define UVWASI_ADVICE_NORMAL 0
+#define UVWASI_ADVICE_SEQUENTIAL 1
+#define UVWASI_ADVICE_RANDOM 2
+#define UVWASI_ADVICE_WILLNEED 3
+#define UVWASI_ADVICE_DONTNEED 4
+#define UVWASI_ADVICE_NOREUSE 5
+
+typedef struct uvwasi_ciovec_s {
+ const void* buf;
+ size_t buf_len;
+} uvwasi_ciovec_t;
+
+typedef uint32_t uvwasi_clockid_t;
+#define UVWASI_CLOCK_REALTIME 0
+#define UVWASI_CLOCK_MONOTONIC 1
+#define UVWASI_CLOCK_PROCESS_CPUTIME_ID 2
+#define UVWASI_CLOCK_THREAD_CPUTIME_ID 3
+
+typedef uint64_t uvwasi_device_t;
+
+typedef uint64_t uvwasi_dircookie_t;
+#define UVWASI_DIRCOOKIE_START 0
+
+typedef uint16_t uvwasi_errno_t;
+#define UVWASI_ESUCCESS 0
+#define UVWASI_E2BIG 1
+#define UVWASI_EACCES 2
+#define UVWASI_EADDRINUSE 3
+#define UVWASI_EADDRNOTAVAIL 4
+#define UVWASI_EAFNOSUPPORT 5
+#define UVWASI_EAGAIN 6
+#define UVWASI_EALREADY 7
+#define UVWASI_EBADF 8
+#define UVWASI_EBADMSG 9
+#define UVWASI_EBUSY 10
+#define UVWASI_ECANCELED 11
+#define UVWASI_ECHILD 12
+#define UVWASI_ECONNABORTED 13
+#define UVWASI_ECONNREFUSED 14
+#define UVWASI_ECONNRESET 15
+#define UVWASI_EDEADLK 16
+#define UVWASI_EDESTADDRREQ 17
+#define UVWASI_EDOM 18
+#define UVWASI_EDQUOT 19
+#define UVWASI_EEXIST 20
+#define UVWASI_EFAULT 21
+#define UVWASI_EFBIG 22
+#define UVWASI_EHOSTUNREACH 23
+#define UVWASI_EIDRM 24
+#define UVWASI_EILSEQ 25
+#define UVWASI_EINPROGRESS 26
+#define UVWASI_EINTR 27
+#define UVWASI_EINVAL 28
+#define UVWASI_EIO 29
+#define UVWASI_EISCONN 30
+#define UVWASI_EISDIR 31
+#define UVWASI_ELOOP 32
+#define UVWASI_EMFILE 33
+#define UVWASI_EMLINK 34
+#define UVWASI_EMSGSIZE 35
+#define UVWASI_EMULTIHOP 36
+#define UVWASI_ENAMETOOLONG 37
+#define UVWASI_ENETDOWN 38
+#define UVWASI_ENETRESET 39
+#define UVWASI_ENETUNREACH 40
+#define UVWASI_ENFILE 41
+#define UVWASI_ENOBUFS 42
+#define UVWASI_ENODEV 43
+#define UVWASI_ENOENT 44
+#define UVWASI_ENOEXEC 45
+#define UVWASI_ENOLCK 46
+#define UVWASI_ENOLINK 47
+#define UVWASI_ENOMEM 48
+#define UVWASI_ENOMSG 49
+#define UVWASI_ENOPROTOOPT 50
+#define UVWASI_ENOSPC 51
+#define UVWASI_ENOSYS 52
+#define UVWASI_ENOTCONN 53
+#define UVWASI_ENOTDIR 54
+#define UVWASI_ENOTEMPTY 55
+#define UVWASI_ENOTRECOVERABLE 56
+#define UVWASI_ENOTSOCK 57
+#define UVWASI_ENOTSUP 58
+#define UVWASI_ENOTTY 59
+#define UVWASI_ENXIO 60
+#define UVWASI_EOVERFLOW 61
+#define UVWASI_EOWNERDEAD 62
+#define UVWASI_EPERM 63
+#define UVWASI_EPIPE 64
+#define UVWASI_EPROTO 65
+#define UVWASI_EPROTONOSUPPORT 66
+#define UVWASI_EPROTOTYPE 67
+#define UVWASI_ERANGE 68
+#define UVWASI_EROFS 69
+#define UVWASI_ESPIPE 70
+#define UVWASI_ESRCH 71
+#define UVWASI_ESTALE 72
+#define UVWASI_ETIMEDOUT 73
+#define UVWASI_ETXTBSY 74
+#define UVWASI_EXDEV 75
+#define UVWASI_ENOTCAPABLE 76
+
+typedef uint16_t uvwasi_eventrwflags_t; /* Bitfield */
+#define UVWASI_EVENT_FD_READWRITE_HANGUP (1 << 0)
+
+typedef uint8_t uvwasi_eventtype_t;
+#define UVWASI_EVENTTYPE_CLOCK 0
+#define UVWASI_EVENTTYPE_FD_READ 1
+#define UVWASI_EVENTTYPE_FD_WRITE 2
+
+typedef uint32_t uvwasi_exitcode_t;
+
+typedef uint32_t uvwasi_fd_t;
+
+typedef uint16_t uvwasi_fdflags_t; /* Bitfield */
+#define UVWASI_FDFLAG_APPEND (1 << 0)
+#define UVWASI_FDFLAG_DSYNC (1 << 1)
+#define UVWASI_FDFLAG_NONBLOCK (1 << 2)
+#define UVWASI_FDFLAG_RSYNC (1 << 3)
+#define UVWASI_FDFLAG_SYNC (1 << 4)
+
+typedef int64_t uvwasi_filedelta_t;
+
+typedef uint64_t uvwasi_filesize_t;
+
+typedef uint8_t uvwasi_filetype_t;
+#define UVWASI_FILETYPE_UNKNOWN 0
+#define UVWASI_FILETYPE_BLOCK_DEVICE 1
+#define UVWASI_FILETYPE_CHARACTER_DEVICE 2
+#define UVWASI_FILETYPE_DIRECTORY 3
+#define UVWASI_FILETYPE_REGULAR_FILE 4
+#define UVWASI_FILETYPE_SOCKET_DGRAM 5
+#define UVWASI_FILETYPE_SOCKET_STREAM 6
+#define UVWASI_FILETYPE_SYMBOLIC_LINK 7
+
+typedef uint16_t uvwasi_fstflags_t; /* Bitfield */
+#define UVWASI_FILESTAT_SET_ATIM (1 << 0)
+#define UVWASI_FILESTAT_SET_ATIM_NOW (1 << 1)
+#define UVWASI_FILESTAT_SET_MTIM (1 << 2)
+#define UVWASI_FILESTAT_SET_MTIM_NOW (1 << 3)
+
+typedef uint64_t uvwasi_inode_t;
+
+typedef struct uvwasi_iovec_s {
+ void* buf;
+ size_t buf_len;
+} uvwasi_iovec_t;
+
+typedef uint64_t uvwasi_linkcount_t;
+
+typedef uint32_t uvwasi_lookupflags_t; /* Bitfield */
+#define UVWASI_LOOKUP_SYMLINK_FOLLOW (1 << 0)
+
+typedef uint16_t uvwasi_oflags_t; /* Bitfield */
+#define UVWASI_O_CREAT (1 << 0)
+#define UVWASI_O_DIRECTORY (1 << 1)
+#define UVWASI_O_EXCL (1 << 2)
+#define UVWASI_O_TRUNC (1 << 3)
+
+typedef uint8_t uvwasi_preopentype_t;
+#define UVWASI_PREOPENTYPE_DIR 0
+
+typedef struct uvwasi_prestat_s {
+ uvwasi_preopentype_t pr_type;
+ union uvwasi_prestat_u {
+ struct uvwasi_prestat_dir_t {
+ size_t pr_name_len;
+ } dir;
+ } u;
+} uvwasi_prestat_t;
+
+typedef uint16_t uvwasi_riflags_t; /* Bitfield */
+#define UVWASI_SOCK_RECV_PEEK (1 << 0)
+#define UVWASI_SOCK_RECV_WAITALL (1 << 1)
+
+typedef uint64_t uvwasi_rights_t; /* Bitfield */
+#define UVWASI_RIGHT_FD_DATASYNC (1 << 0)
+#define UVWASI_RIGHT_FD_READ (1 << 1)
+#define UVWASI_RIGHT_FD_SEEK (1 << 2)
+#define UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS (1 << 3)
+#define UVWASI_RIGHT_FD_SYNC (1 << 4)
+#define UVWASI_RIGHT_FD_TELL (1 << 5)
+#define UVWASI_RIGHT_FD_WRITE (1 << 6)
+#define UVWASI_RIGHT_FD_ADVISE (1 << 7)
+#define UVWASI_RIGHT_FD_ALLOCATE (1 << 8)
+#define UVWASI_RIGHT_PATH_CREATE_DIRECTORY (1 << 9)
+#define UVWASI_RIGHT_PATH_CREATE_FILE (1 << 10)
+#define UVWASI_RIGHT_PATH_LINK_SOURCE (1 << 11)
+#define UVWASI_RIGHT_PATH_LINK_TARGET (1 << 12)
+#define UVWASI_RIGHT_PATH_OPEN (1 << 13)
+#define UVWASI_RIGHT_FD_READDIR (1 << 14)
+#define UVWASI_RIGHT_PATH_READLINK (1 << 15)
+#define UVWASI_RIGHT_PATH_RENAME_SOURCE (1 << 16)
+#define UVWASI_RIGHT_PATH_RENAME_TARGET (1 << 17)
+#define UVWASI_RIGHT_PATH_FILESTAT_GET (1 << 18)
+#define UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE (1 << 19)
+#define UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES (1 << 20)
+#define UVWASI_RIGHT_FD_FILESTAT_GET (1 << 21)
+#define UVWASI_RIGHT_FD_FILESTAT_SET_SIZE (1 << 22)
+#define UVWASI_RIGHT_FD_FILESTAT_SET_TIMES (1 << 23)
+#define UVWASI_RIGHT_PATH_SYMLINK (1 << 24)
+#define UVWASI_RIGHT_PATH_REMOVE_DIRECTORY (1 << 25)
+#define UVWASI_RIGHT_PATH_UNLINK_FILE (1 << 26)
+#define UVWASI_RIGHT_POLL_FD_READWRITE (1 << 27)
+#define UVWASI_RIGHT_SOCK_SHUTDOWN (1 << 28)
+
+typedef uint16_t uvwasi_roflags_t; /* Bitfield */
+#define UVWASI_SOCK_RECV_DATA_TRUNCATED (1 << 0)
+
+typedef uint8_t uvwasi_sdflags_t; /* Bitfield */
+#define UVWASI_SHUT_RD (1 << 0)
+#define UVWASI_SHUT_WR (1 << 1)
+
+typedef uint16_t uvwasi_siflags_t; /* Bitfield */
+
+typedef uint8_t uvwasi_signal_t;
+#define UVWASI_SIGHUP 1
+#define UVWASI_SIGINT 2
+#define UVWASI_SIGQUIT 3
+#define UVWASI_SIGILL 4
+#define UVWASI_SIGTRAP 5
+#define UVWASI_SIGABRT 6
+#define UVWASI_SIGBUS 7
+#define UVWASI_SIGFPE 8
+#define UVWASI_SIGKILL 9
+#define UVWASI_SIGUSR1 10
+#define UVWASI_SIGSEGV 11
+#define UVWASI_SIGUSR2 12
+#define UVWASI_SIGPIPE 13
+#define UVWASI_SIGALRM 14
+#define UVWASI_SIGTERM 15
+#define UVWASI_SIGCHLD 16
+#define UVWASI_SIGCONT 17
+#define UVWASI_SIGSTOP 18
+#define UVWASI_SIGTSTP 19
+#define UVWASI_SIGTTIN 20
+#define UVWASI_SIGTTOU 21
+#define UVWASI_SIGURG 22
+#define UVWASI_SIGXCPU 23
+#define UVWASI_SIGXFSZ 24
+#define UVWASI_SIGVTALRM 25
+#define UVWASI_SIGPROF 26
+#define UVWASI_SIGWINCH 27
+#define UVWASI_SIGPOLL 28
+#define UVWASI_SIGPWR 29
+#define UVWASI_SIGSYS 30
+
+typedef uint16_t uvwasi_subclockflags_t; /* Bitfield */
+#define UVWASI_SUBSCRIPTION_CLOCK_ABSTIME (1 << 0)
+
+typedef uint64_t uvwasi_timestamp_t;
+
+typedef uint64_t uvwasi_userdata_t;
+
+typedef struct uvwasi_subscription_s {
+ uvwasi_userdata_t userdata;
+ uvwasi_eventtype_t type;
+ union {
+ struct {
+ uvwasi_clockid_t clock_id;
+ uvwasi_timestamp_t timeout;
+ uvwasi_timestamp_t precision;
+ uvwasi_subclockflags_t flags;
+ } clock;
+ struct {
+ uvwasi_fd_t fd;
+ } fd_readwrite;
+ } u;
+} uvwasi_subscription_t;
+
+typedef struct uvwasi_dirent_s {
+ uvwasi_dircookie_t d_next;
+ uvwasi_inode_t d_ino;
+ uint32_t d_namlen;
+ uvwasi_filetype_t d_type;
+} uvwasi_dirent_t;
+
+typedef struct uvwasi_fdstat_s {
+ uvwasi_filetype_t fs_filetype;
+ uvwasi_fdflags_t fs_flags;
+ uvwasi_rights_t fs_rights_base;
+ uvwasi_rights_t fs_rights_inheriting;
+} uvwasi_fdstat_t;
+
+typedef struct uvwasi_filestat_s {
+ uvwasi_device_t st_dev;
+ uvwasi_inode_t st_ino;
+ uvwasi_filetype_t st_filetype;
+ uvwasi_linkcount_t st_nlink;
+ uvwasi_filesize_t st_size;
+ uvwasi_timestamp_t st_atim;
+ uvwasi_timestamp_t st_mtim;
+ uvwasi_timestamp_t st_ctim;
+} uvwasi_filestat_t;
+
+typedef struct uvwasi_event_s {
+ uvwasi_userdata_t userdata;
+ uvwasi_errno_t error;
+ uvwasi_eventtype_t type;
+ union {
+ struct {
+ uvwasi_filesize_t nbytes;
+ uvwasi_eventrwflags_t flags;
+ } fd_readwrite;
+ } u;
+} uvwasi_event_t;
+
+typedef uint8_t uvwasi_whence_t;
+#define UVWASI_WHENCE_SET 0
+#define UVWASI_WHENCE_CUR 1
+#define UVWASI_WHENCE_END 2
+
+#endif /* __UVWASI_WASI_TYPES_H__ */
diff --git a/deps/uvwasi/src/clocks.c b/deps/uvwasi/src/clocks.c
new file mode 100644
index 00000000000000..e1fbc696b62f05
--- /dev/null
+++ b/deps/uvwasi/src/clocks.c
@@ -0,0 +1,194 @@
+#ifndef _WIN32
+# include
+# include
+# include
+# include
+#endif /* _WIN32 */
+
+#include "uv.h"
+#include "wasi_types.h"
+#include "uv_mapping.h"
+
+
+#define UVWASI__WIN_TIME_AND_RETURN(handle, time) \
+ do { \
+ FILETIME create; \
+ FILETIME exit; \
+ FILETIME system; \
+ FILETIME user; \
+ SYSTEMTIME sys_system; \
+ SYSTEMTIME sys_user; \
+ if (0 == GetProcessTimes((handle), &create, &exit, &system, &user)) { \
+ return uvwasi__translate_uv_error( \
+ uv_translate_sys_error(GetLastError()) \
+ ); \
+ } \
+ \
+ if (0 == FileTimeToSystemTime(&system, &sys_system)) { \
+ return uvwasi__translate_uv_error( \
+ uv_translate_sys_error(GetLastError()) \
+ ); \
+ } \
+ \
+ if (0 == FileTimeToSystemTime(&user, &sys_user)) { \
+ return uvwasi__translate_uv_error( \
+ uv_translate_sys_error(GetLastError()) \
+ ); \
+ } \
+ \
+ (time) = (((sys_system.wHour * 3600) + (sys_system.wMinute * 60) + \
+ sys_system.wSecond) * NANOS_PER_SEC) + \
+ (sys_system.wMilliseconds * 1000000) + \
+ (((sys_user.wHour * 3600) + (sys_user.wMinute * 60) + \
+ sys_user.wSecond) * NANOS_PER_SEC) + \
+ (sys_user.wMilliseconds * 1000000); \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__CLOCK_GETTIME_AND_RETURN(clk, time) \
+ do { \
+ struct timespec ts; \
+ if (0 != clock_gettime((clk), &ts)) \
+ return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \
+ (time) = (ts.tv_sec * NANOS_PER_SEC) + ts.tv_nsec; \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__GETRUSAGE_AND_RETURN(who, time) \
+ do { \
+ struct rusage ru; \
+ if (0 != getrusage((who), &ru)) \
+ return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \
+ (time) = (ru.ru_utime.tv_sec * NANOS_PER_SEC) + \
+ (ru.ru_utime.tv_usec * 1000) + \
+ (ru.ru_stime.tv_sec * NANOS_PER_SEC) + \
+ (ru.ru_stime.tv_usec * 1000); \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__OSX_THREADTIME_AND_RETURN(time) \
+ do { \
+ mach_port_t thread; \
+ thread_basic_info_data_t info; \
+ mach_msg_type_number_t count; \
+ count = THREAD_BASIC_INFO_COUNT; \
+ thread = pthread_mach_thread_np(pthread_self()); \
+ if (KERN_SUCCESS != thread_info(thread, \
+ THREAD_BASIC_INFO, \
+ (thread_info_t) &info, \
+ &count)) { \
+ return UVWASI_ENOSYS; \
+ } \
+ (time) = (info.user_time.seconds * NANOS_PER_SEC) + \
+ (info.user_time.microseconds * 1000) + \
+ (info.system_time.seconds * NANOS_PER_SEC) + \
+ (info.system_time.microseconds * 1000); \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__WIN_GETRES_AND_RETURN(time) \
+ do { \
+ /* The GetProcessTimes() docs claim a resolution of 100 ns. */ \
+ (time) = 100; \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__CLOCK_GETRES_AND_RETURN(clk, time) \
+ do { \
+ struct timespec ts; \
+ /* Try calling clock_getres(). If it doesn't succeed, then default to \
+ 1000000. We implement all of the clocks, and some platforms (such as \
+ SmartOS) don't support all of the clocks, even though they define \
+ the constants for them. */ \
+ if (0 != clock_getres((clk), &ts)) \
+ (time) = 1000000; \
+ else \
+ (time) = (ts.tv_sec * NANOS_PER_SEC) + ts.tv_nsec; \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+#define UVWASI__SLOW_GETRES_AND_RETURN(time) \
+ do { \
+ /* Assume a "worst case" of 1000000 ns resolution. */ \
+ (time) = 1000000; \
+ return UVWASI_ESUCCESS; \
+ } while (0)
+
+
+uvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time) {
+ uv_timeval64_t tv;
+ int r;
+
+ r = uv_gettimeofday(&tv);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ *time = (tv.tv_sec * NANOS_PER_SEC) + (tv.tv_usec * 1000);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time) {
+#if defined(_WIN32)
+ UVWASI__WIN_TIME_AND_RETURN(GetCurrentProcess(), *time);
+#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \
+ !defined(__APPLE__) && \
+ !defined(__sun)
+ UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time);
+#else
+ UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_SELF, *time);
+#endif
+}
+
+
+uvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time) {
+#if defined(_WIN32)
+ UVWASI__WIN_TIME_AND_RETURN(GetCurrentThread(), *time);
+#elif defined(__APPLE__)
+ UVWASI__OSX_THREADTIME_AND_RETURN(*time);
+#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun)
+ UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time);
+#else
+# if defined(RUSAGE_LWP)
+ UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_LWP, *time);
+# elif defined(RUSAGE_THREAD)
+ UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_THREAD, *time);
+# else
+ return UVWASI_ENOSYS;
+# endif /* RUSAGE_LWP */
+#endif
+}
+
+
+uvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time) {
+#if defined(_WIN32)
+ UVWASI__WIN_GETRES_AND_RETURN(*time);
+#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \
+ !defined(__APPLE__) && \
+ !defined(__sun)
+ UVWASI__CLOCK_GETRES_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time);
+#else
+ UVWASI__SLOW_GETRES_AND_RETURN(*time);
+#endif
+}
+
+
+uvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time) {
+#if defined(_WIN32)
+ UVWASI__WIN_GETRES_AND_RETURN(*time);
+#elif defined(__APPLE__)
+ UVWASI__SLOW_GETRES_AND_RETURN(*time);
+#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun)
+ UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time);
+#elif defined(RUSAGE_THREAD) || defined(RUSAGE_LWP)
+ UVWASI__SLOW_GETRES_AND_RETURN(*time);
+#else
+ return UVWASI_ENOSYS;
+#endif
+}
diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c
new file mode 100644
index 00000000000000..f3855d4da54dbe
--- /dev/null
+++ b/deps/uvwasi/src/fd_table.c
@@ -0,0 +1,524 @@
+#include
+#include
+#include
+
+#ifndef _WIN32
+# include
+#endif /* _WIN32 */
+
+#include "uv.h"
+#include "fd_table.h"
+#include "wasi_types.h"
+#include "uv_mapping.h"
+#include "uvwasi_alloc.h"
+
+
+#define UVWASI__RIGHTS_ALL (UVWASI_RIGHT_FD_DATASYNC | \
+ UVWASI_RIGHT_FD_READ | \
+ UVWASI_RIGHT_FD_SEEK | \
+ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
+ UVWASI_RIGHT_FD_SYNC | \
+ UVWASI_RIGHT_FD_TELL | \
+ UVWASI_RIGHT_FD_WRITE | \
+ UVWASI_RIGHT_FD_ADVISE | \
+ UVWASI_RIGHT_FD_ALLOCATE | \
+ UVWASI_RIGHT_PATH_CREATE_DIRECTORY | \
+ UVWASI_RIGHT_PATH_CREATE_FILE | \
+ UVWASI_RIGHT_PATH_LINK_SOURCE | \
+ UVWASI_RIGHT_PATH_LINK_TARGET | \
+ UVWASI_RIGHT_PATH_OPEN | \
+ UVWASI_RIGHT_FD_READDIR | \
+ UVWASI_RIGHT_PATH_READLINK | \
+ UVWASI_RIGHT_PATH_RENAME_SOURCE | \
+ UVWASI_RIGHT_PATH_RENAME_TARGET | \
+ UVWASI_RIGHT_PATH_FILESTAT_GET | \
+ UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
+ UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
+ UVWASI_RIGHT_FD_FILESTAT_GET | \
+ UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
+ UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
+ UVWASI_RIGHT_PATH_SYMLINK | \
+ UVWASI_RIGHT_PATH_UNLINK_FILE | \
+ UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
+ UVWASI_RIGHT_POLL_FD_READWRITE | \
+ UVWASI_RIGHT_SOCK_SHUTDOWN)
+
+#define UVWASI__RIGHTS_BLOCK_DEVICE_BASE UVWASI__RIGHTS_ALL
+#define UVWASI__RIGHTS_BLOCK_DEVICE_INHERITING UVWASI__RIGHTS_ALL
+
+#define UVWASI__RIGHTS_CHARACTER_DEVICE_BASE UVWASI__RIGHTS_ALL
+#define UVWASI__RIGHTS_CHARACTER_DEVICE_INHERITING UVWASI__RIGHTS_ALL
+
+#define UVWASI__RIGHTS_REGULAR_FILE_BASE (UVWASI_RIGHT_FD_DATASYNC | \
+ UVWASI_RIGHT_FD_READ | \
+ UVWASI_RIGHT_FD_SEEK | \
+ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
+ UVWASI_RIGHT_FD_SYNC | \
+ UVWASI_RIGHT_FD_TELL | \
+ UVWASI_RIGHT_FD_WRITE | \
+ UVWASI_RIGHT_FD_ADVISE | \
+ UVWASI_RIGHT_FD_ALLOCATE | \
+ UVWASI_RIGHT_FD_FILESTAT_GET | \
+ UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
+ UVWASI_RIGHT_FD_FILESTAT_SET_TIMES |\
+ UVWASI_RIGHT_POLL_FD_READWRITE)
+#define UVWASI__RIGHTS_REGULAR_FILE_INHERITING 0
+
+#define UVWASI__RIGHTS_DIRECTORY_BASE (UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
+ UVWASI_RIGHT_FD_SYNC | \
+ UVWASI_RIGHT_FD_ADVISE | \
+ UVWASI_RIGHT_PATH_CREATE_DIRECTORY | \
+ UVWASI_RIGHT_PATH_CREATE_FILE | \
+ UVWASI_RIGHT_PATH_LINK_SOURCE | \
+ UVWASI_RIGHT_PATH_LINK_TARGET | \
+ UVWASI_RIGHT_PATH_OPEN | \
+ UVWASI_RIGHT_FD_READDIR | \
+ UVWASI_RIGHT_PATH_READLINK | \
+ UVWASI_RIGHT_PATH_RENAME_SOURCE | \
+ UVWASI_RIGHT_PATH_RENAME_TARGET | \
+ UVWASI_RIGHT_PATH_FILESTAT_GET | \
+ UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
+ UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
+ UVWASI_RIGHT_FD_FILESTAT_GET | \
+ UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
+ UVWASI_RIGHT_PATH_SYMLINK | \
+ UVWASI_RIGHT_PATH_UNLINK_FILE | \
+ UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
+ UVWASI_RIGHT_POLL_FD_READWRITE)
+#define UVWASI__RIGHTS_DIRECTORY_INHERITING (UVWASI__RIGHTS_DIRECTORY_BASE | \
+ UVWASI__RIGHTS_REGULAR_FILE_BASE)
+
+#define UVWASI__RIGHTS_SOCKET_BASE (UVWASI_RIGHT_FD_READ | \
+ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
+ UVWASI_RIGHT_FD_WRITE | \
+ UVWASI_RIGHT_FD_FILESTAT_GET | \
+ UVWASI_RIGHT_POLL_FD_READWRITE | \
+ UVWASI_RIGHT_SOCK_SHUTDOWN)
+#define UVWASI__RIGHTS_SOCKET_INHERITING UVWASI__RIGHTS_ALL;
+
+#define UVWASI__RIGHTS_TTY_BASE (UVWASI_RIGHT_FD_READ | \
+ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
+ UVWASI_RIGHT_FD_WRITE | \
+ UVWASI_RIGHT_FD_FILESTAT_GET | \
+ UVWASI_RIGHT_POLL_FD_READWRITE)
+#define UVWASI__RIGHTS_TTY_INHERITING 0
+
+static uvwasi_errno_t uvwasi__get_type_and_rights(uv_file fd,
+ int flags,
+ uvwasi_filetype_t* type,
+ uvwasi_rights_t* rights_base,
+ uvwasi_rights_t* rights_inheriting) {
+ uv_fs_t req;
+ uvwasi_filetype_t filetype;
+ int read_or_write_only;
+ int r;
+
+ r = uv_fs_fstat(NULL, &req, fd, NULL);
+ filetype = uvwasi__stat_to_filetype(&req.statbuf);
+ uv_fs_req_cleanup(&req);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ *type = filetype;
+ switch (filetype) {
+ case UVWASI_FILETYPE_REGULAR_FILE:
+ *rights_base = UVWASI__RIGHTS_REGULAR_FILE_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_REGULAR_FILE_INHERITING;
+ break;
+
+ case UVWASI_FILETYPE_DIRECTORY:
+ *rights_base = UVWASI__RIGHTS_DIRECTORY_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_DIRECTORY_INHERITING;
+ break;
+
+ /* uvwasi__stat_to_filetype() cannot differentiate socket types. It only
+ returns UVWASI_FILETYPE_SOCKET_STREAM. */
+ case UVWASI_FILETYPE_SOCKET_STREAM:
+ if (uv_guess_handle(fd) == UV_UDP)
+ *type = UVWASI_FILETYPE_SOCKET_DGRAM;
+
+ *rights_base = UVWASI__RIGHTS_SOCKET_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_SOCKET_INHERITING;
+ break;
+
+ case UVWASI_FILETYPE_CHARACTER_DEVICE:
+ if (uv_guess_handle(fd) == UV_TTY) {
+ *rights_base = UVWASI__RIGHTS_TTY_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_TTY_INHERITING;
+ } else {
+ *rights_base = UVWASI__RIGHTS_CHARACTER_DEVICE_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_CHARACTER_DEVICE_INHERITING;
+ }
+ break;
+
+ case UVWASI_FILETYPE_BLOCK_DEVICE:
+ *rights_base = UVWASI__RIGHTS_BLOCK_DEVICE_BASE;
+ *rights_inheriting = UVWASI__RIGHTS_BLOCK_DEVICE_INHERITING;
+ break;
+
+ default:
+ *rights_base = 0;
+ *rights_inheriting = 0;
+ }
+
+ if (*type == UVWASI_FILETYPE_UNKNOWN)
+ return UVWASI_EINVAL;
+
+ /* Disable read/write bits depending on access mode. */
+ read_or_write_only = flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
+
+ if (read_or_write_only == UV_FS_O_RDONLY)
+ *rights_base &= ~UVWASI_RIGHT_FD_WRITE;
+ else if (read_or_write_only == UV_FS_O_WRONLY)
+ *rights_base &= ~UVWASI_RIGHT_FD_READ;
+
+ return UVWASI_ESUCCESS;
+}
+
+
+static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ uv_file fd,
+ const char* mapped_path,
+ const char* real_path,
+ uvwasi_filetype_t type,
+ uvwasi_rights_t rights_base,
+ uvwasi_rights_t rights_inheriting,
+ int preopen,
+ struct uvwasi_fd_wrap_t** wrap) {
+ struct uvwasi_fd_wrap_t* entry;
+ struct uvwasi_fd_wrap_t** new_fds;
+ uvwasi_errno_t err;
+ uint32_t new_size;
+ int index;
+ uint32_t i;
+ int r;
+ size_t mp_len;
+ char* mp_copy;
+ size_t rp_len;
+ char* rp_copy;
+
+ mp_len = strlen(mapped_path);
+ rp_len = strlen(real_path);
+ entry = (struct uvwasi_fd_wrap_t*)
+ uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + rp_len + 2);
+ if (entry == NULL) return UVWASI_ENOMEM;
+
+ mp_copy = (char*)(entry + 1);
+ rp_copy = mp_copy + mp_len + 1;
+ memcpy(mp_copy, mapped_path, mp_len);
+ mp_copy[mp_len] = '\0';
+ memcpy(rp_copy, real_path, rp_len);
+ rp_copy[rp_len] = '\0';
+
+ uv_rwlock_wrlock(&table->rwlock);
+
+ /* Check that there is room for a new item. If there isn't, grow the table. */
+ if (table->used >= table->size) {
+ new_size = table->size * 2;
+ new_fds = uvwasi__realloc(uvwasi, table->fds, new_size * sizeof(*new_fds));
+ if (new_fds == NULL) {
+ uvwasi__free(uvwasi, entry);
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ for (i = table->size; i < new_size; ++i)
+ new_fds[i] = NULL;
+
+ index = table->size;
+ table->fds = new_fds;
+ table->size = new_size;
+ } else {
+ /* The table is big enough, so find an empty slot for the new data. */
+ index = -1;
+ for (i = 0; i < table->size; ++i) {
+ if (table->fds[i] == NULL) {
+ index = i;
+ break;
+ }
+ }
+
+ /* index should never be -1. */
+ if (index == -1) {
+ uvwasi__free(uvwasi, entry);
+ err = UVWASI_ENOSPC;
+ goto exit;
+ }
+ }
+
+ table->fds[index] = entry;
+
+ r = uv_mutex_init(&entry->mutex);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ entry->id = index;
+ entry->fd = fd;
+ entry->path = mp_copy;
+ entry->real_path = rp_copy;
+ entry->type = type;
+ entry->rights_base = rights_base;
+ entry->rights_inheriting = rights_inheriting;
+ entry->preopen = preopen;
+ table->used++;
+
+ if (wrap != NULL)
+ *wrap = entry;
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_wrunlock(&table->rwlock);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ uint32_t init_size) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_filetype_t type;
+ uvwasi_rights_t base;
+ uvwasi_rights_t inheriting;
+ uvwasi_errno_t err;
+ uvwasi_fd_t i;
+ int r;
+
+ /* Require an initial size of at least three to store the stdio FDs. */
+ if (table == NULL || init_size < 3)
+ return UVWASI_EINVAL;
+
+ table->fds = NULL;
+ table->used = 0;
+ table->size = init_size;
+ table->fds = uvwasi__calloc(uvwasi,
+ init_size,
+ sizeof(struct uvwasi_fd_wrap_t*));
+
+ if (table->fds == NULL)
+ 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;
+ return err;
+ }
+
+ /* Create the stdio FDs. */
+ for (i = 0; i < 3; ++i) {
+ err = uvwasi__get_type_and_rights(i,
+ UV_FS_O_RDWR,
+ &type,
+ &base,
+ &inheriting);
+ if (err != UVWASI_ESUCCESS)
+ goto error_exit;
+
+ err = uvwasi__fd_table_insert(uvwasi,
+ table,
+ i,
+ "",
+ "",
+ type,
+ base,
+ inheriting,
+ 0,
+ &wrap);
+ if (err != UVWASI_ESUCCESS)
+ goto error_exit;
+
+ if (wrap->id != i || wrap->id != (uvwasi_fd_t) wrap->fd) {
+ err = UVWASI_EBADF;
+ goto error_exit;
+ }
+ }
+
+ return UVWASI_ESUCCESS;
+error_exit:
+ uvwasi_fd_table_free(uvwasi, table);
+ return err;
+}
+
+
+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)
+ return;
+
+ for (i = 0; i < table->size; i++) {
+ entry = table->fds[i];
+ if (entry == NULL) continue;
+
+ uv_mutex_destroy(&entry->mutex);
+ uvwasi__free(uvwasi, entry);
+ }
+
+ if (table->fds != NULL) {
+ uvwasi__free(uvwasi, table->fds);
+ table->fds = NULL;
+ table->size = 0;
+ table->used = 0;
+ uv_rwlock_destroy(&table->rwlock);
+ }
+}
+
+
+uvwasi_errno_t uvwasi_fd_table_insert_preopen(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uv_file fd,
+ const char* path,
+ const char* real_path) {
+ uvwasi_filetype_t type;
+ uvwasi_rights_t base;
+ uvwasi_rights_t inheriting;
+ uvwasi_errno_t err;
+
+ if (table == NULL || path == NULL || real_path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi__get_type_and_rights(fd, 0, &type, &base, &inheriting);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ if (type != UVWASI_FILETYPE_DIRECTORY)
+ return UVWASI_ENOTDIR;
+
+ err = uvwasi__fd_table_insert(uvwasi,
+ table,
+ fd,
+ path,
+ real_path,
+ UVWASI_FILETYPE_DIRECTORY,
+ UVWASI__RIGHTS_DIRECTORY_BASE,
+ UVWASI__RIGHTS_DIRECTORY_INHERITING,
+ 1,
+ NULL);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_table_insert_fd(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uv_file fd,
+ const int flags,
+ const char* path,
+ uvwasi_rights_t rights_base,
+ uvwasi_rights_t rights_inheriting,
+ struct uvwasi_fd_wrap_t* wrap) {
+ struct uvwasi_fd_wrap_t* fd_wrap;
+ uvwasi_filetype_t type;
+ uvwasi_rights_t max_base;
+ uvwasi_rights_t max_inheriting;
+ uvwasi_errno_t r;
+
+ if (table == NULL || path == NULL || wrap == NULL)
+ return UVWASI_EINVAL;
+
+ r = uvwasi__get_type_and_rights(fd, flags, &type, &max_base, &max_inheriting);
+ if (r != UVWASI_ESUCCESS)
+ return r;
+
+ r = uvwasi__fd_table_insert(uvwasi,
+ table,
+ fd,
+ path,
+ path,
+ type,
+ rights_base & max_base,
+ rights_inheriting & max_inheriting,
+ 0,
+ &fd_wrap);
+ if (r != UVWASI_ESUCCESS)
+ return r;
+
+ *wrap = *fd_wrap;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
+ const uvwasi_fd_t id,
+ struct uvwasi_fd_wrap_t** wrap,
+ uvwasi_rights_t rights_base,
+ uvwasi_rights_t rights_inheriting) {
+ struct uvwasi_fd_wrap_t* entry;
+ uvwasi_errno_t err;
+
+ if (table == NULL || wrap == NULL)
+ return UVWASI_EINVAL;
+
+ uv_rwlock_rdlock((uv_rwlock_t *)&table->rwlock);
+
+ if (id >= table->size) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+
+ entry = table->fds[id];
+
+ if (entry == NULL || entry->id != id) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+
+ /* Validate that the fd has the necessary rights. */
+ if ((~entry->rights_base & rights_base) != 0 ||
+ (~entry->rights_inheriting & rights_inheriting) != 0) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+
+ uv_mutex_lock(&entry->mutex);
+ *wrap = entry;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_rdunlock((uv_rwlock_t *)&table->rwlock);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_table_remove(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
+ const uvwasi_fd_t id) {
+ struct uvwasi_fd_wrap_t* entry;
+ uvwasi_errno_t err;
+
+ if (table == NULL)
+ return UVWASI_EINVAL;
+
+ uv_rwlock_wrlock(&table->rwlock);
+
+ if (id >= table->size) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+
+ entry = table->fds[id];
+
+ if (entry == NULL || entry->id != id) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+
+ uv_mutex_destroy(&entry->mutex);
+ uvwasi__free(uvwasi, entry);
+ table->fds[id] = NULL;
+ table->used--;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_wrunlock(&table->rwlock);
+ return err;
+}
diff --git a/deps/uvwasi/src/uv_mapping.c b/deps/uvwasi/src/uv_mapping.c
new file mode 100644
index 00000000000000..846dcedbeb6b4f
--- /dev/null
+++ b/deps/uvwasi/src/uv_mapping.c
@@ -0,0 +1,243 @@
+#include
+
+#ifndef _WIN32
+# include
+#endif /* _WIN32 */
+
+#include "uv.h"
+#include "wasi_types.h"
+#include "uv_mapping.h"
+
+#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#if !defined(S_ISCHR) && defined(S_IFMT) && defined(S_IFCHR)
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+
+#if !defined(S_ISLNK) && defined(S_IFMT) && defined(S_IFLNK)
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#endif
+
+
+uvwasi_errno_t uvwasi__translate_uv_error(int err) {
+ switch (err) {
+ case UV_E2BIG: return UVWASI_E2BIG;
+ case UV_EACCES: return UVWASI_EACCES;
+ case UV_EADDRINUSE: return UVWASI_EADDRINUSE;
+ case UV_EADDRNOTAVAIL: return UVWASI_EADDRNOTAVAIL;
+ case UV_EAFNOSUPPORT: return UVWASI_EAFNOSUPPORT;
+ case UV_EAGAIN: return UVWASI_EAGAIN;
+ case UV_EALREADY: return UVWASI_EALREADY;
+ case UV_EBADF: return UVWASI_EBADF;
+ case UV_EBUSY: return UVWASI_EBUSY;
+ case UV_ECANCELED: return UVWASI_ECANCELED;
+ case UV_ECONNABORTED: return UVWASI_ECONNABORTED;
+ case UV_ECONNREFUSED: return UVWASI_ECONNREFUSED;
+ case UV_ECONNRESET: return UVWASI_ECONNRESET;
+ case UV_EDESTADDRREQ: return UVWASI_EDESTADDRREQ;
+ case UV_EEXIST: return UVWASI_EEXIST;
+ case UV_EFAULT: return UVWASI_EFAULT;
+ case UV_EFBIG: return UVWASI_EFBIG;
+ case UV_EHOSTUNREACH: return UVWASI_EHOSTUNREACH;
+ case UV_EINTR: return UVWASI_EINTR;
+ case UV_EINVAL: return UVWASI_EINVAL;
+ case UV_EIO: return UVWASI_EIO;
+ case UV_EISCONN: return UVWASI_EISCONN;
+ case UV_EISDIR: return UVWASI_EISDIR;
+ case UV_ELOOP: return UVWASI_ELOOP;
+ case UV_EMFILE: return UVWASI_EMFILE;
+ case UV_EMLINK: return UVWASI_EMLINK;
+ case UV_EMSGSIZE: return UVWASI_EMSGSIZE;
+ case UV_ENAMETOOLONG: return UVWASI_ENAMETOOLONG;
+ case UV_ENETDOWN: return UVWASI_ENETDOWN;
+ case UV_ENETUNREACH: return UVWASI_ENETUNREACH;
+ case UV_ENFILE: return UVWASI_ENFILE;
+ case UV_ENOBUFS: return UVWASI_ENOBUFS;
+ case UV_ENODEV: return UVWASI_ENODEV;
+ case UV_ENOENT: return UVWASI_ENOENT;
+ case UV_ENOMEM: return UVWASI_ENOMEM;
+ case UV_ENOPROTOOPT: return UVWASI_ENOPROTOOPT;
+ case UV_ENOSPC: return UVWASI_ENOSPC;
+ case UV_ENOSYS: return UVWASI_ENOSYS;
+ case UV_ENOTCONN: return UVWASI_ENOTCONN;
+ case UV_ENOTDIR: return UVWASI_ENOTDIR;
+ /* On at least some AIX machines, ENOTEMPTY and EEXIST are equivalent. */
+#if ENOTEMPTY != EEXIST
+ case UV_ENOTEMPTY: return UVWASI_ENOTEMPTY;
+#endif /* ENOTEMPTY != EEXIST */
+ case UV_ENOTSOCK: return UVWASI_ENOTSOCK;
+ case UV_ENOTSUP: return UVWASI_ENOTSUP;
+ case UV_ENXIO: return UVWASI_ENXIO;
+ case UV_EPERM: return UVWASI_EPERM;
+ case UV_EPIPE: return UVWASI_EPIPE;
+ case UV_EPROTO: return UVWASI_EPROTO;
+ case UV_EPROTONOSUPPORT: return UVWASI_EPROTONOSUPPORT;
+ case UV_EPROTOTYPE: return UVWASI_EPROTOTYPE;
+ case UV_ERANGE: return UVWASI_ERANGE;
+ case UV_EROFS: return UVWASI_EROFS;
+ case UV_ESPIPE: return UVWASI_ESPIPE;
+ case UV_ESRCH: return UVWASI_ESRCH;
+ case UV_ETIMEDOUT: return UVWASI_ETIMEDOUT;
+ case UV_ETXTBSY: return UVWASI_ETXTBSY;
+ case UV_EXDEV: return UVWASI_EXDEV;
+ case 0: return UVWASI_ESUCCESS;
+ /* The following libuv error codes have no corresponding WASI error code:
+ UV_EAI_ADDRFAMILY, UV_EAI_AGAIN, UV_EAI_BADFLAGS, UV_EAI_BADHINTS,
+ UV_EAI_CANCELED, UV_EAI_FAIL, UV_EAI_FAMILY, UV_EAI_MEMORY,
+ UV_EAI_NODATA, UV_EAI_NONAME, UV_EAI_OVERFLOW, UV_EAI_PROTOCOL,
+ UV_EAI_SERVICE, UV_EAI_SOCKTYPE, UV_ECHARSET, UV_ENONET, UV_EOF,
+ UV_ESHUTDOWN, UV_UNKNOWN
+ */
+ default:
+ /* libuv errors are < 0 */
+ if (err > 0)
+ return err;
+
+ return UVWASI_ENOSYS;
+ }
+}
+
+
+int uvwasi__translate_to_uv_signal(uvwasi_signal_t sig) {
+ switch (sig) {
+#ifdef SIGABRT
+ case UVWASI_SIGABRT: return SIGABRT;
+#endif
+#ifdef SIGALRM
+ case UVWASI_SIGALRM: return SIGALRM;
+#endif
+#ifdef SIGBUS
+ case UVWASI_SIGBUS: return SIGBUS;
+#endif
+#ifdef SIGCHLD
+ case UVWASI_SIGCHLD: return SIGCHLD;
+#endif
+#ifdef SIGCONT
+ case UVWASI_SIGCONT: return SIGCONT;
+#endif
+#ifdef SIGFPE
+ case UVWASI_SIGFPE: return SIGFPE;
+#endif
+#ifdef SIGHUP
+ case UVWASI_SIGHUP: return SIGHUP;
+#endif
+#ifdef SIGILL
+ case UVWASI_SIGILL: return SIGILL;
+#endif
+#ifdef SIGINT
+ case UVWASI_SIGINT: return SIGINT;
+#endif
+#ifdef SIGKILL
+ case UVWASI_SIGKILL: return SIGKILL;
+#endif
+#ifdef SIGPIPE
+ case UVWASI_SIGPIPE: return SIGPIPE;
+#endif
+#ifdef SIGQUIT
+ case UVWASI_SIGQUIT: return SIGQUIT;
+#endif
+#ifdef SIGSEGV
+ case UVWASI_SIGSEGV: return SIGSEGV;
+#endif
+#ifdef SIGSTOP
+ case UVWASI_SIGSTOP: return SIGSTOP;
+#endif
+#ifdef SIGSYS
+ case UVWASI_SIGSYS: return SIGSYS;
+#endif
+#ifdef SIGTERM
+ case UVWASI_SIGTERM: return SIGTERM;
+#endif
+#ifdef SIGTRAP
+ case UVWASI_SIGTRAP: return SIGTRAP;
+#endif
+#ifdef SIGTSTP
+ case UVWASI_SIGTSTP: return SIGTSTP;
+#endif
+#ifdef SIGTTIN
+ case UVWASI_SIGTTIN: return SIGTTIN;
+#endif
+#ifdef SIGTTOU
+ case UVWASI_SIGTTOU: return SIGTTOU;
+#endif
+#ifdef SIGURG
+ case UVWASI_SIGURG: return SIGURG;
+#endif
+#ifdef SIGUSR1
+ case UVWASI_SIGUSR1: return SIGUSR1;
+#endif
+#ifdef SIGUSR2
+ case UVWASI_SIGUSR2: return SIGUSR2;
+#endif
+#ifdef SIGVTALRM
+ case UVWASI_SIGVTALRM: return SIGVTALRM;
+#endif
+#ifdef SIGXCPU
+ case UVWASI_SIGXCPU: return SIGXCPU;
+#endif
+#ifdef SIGXFSZ
+ case UVWASI_SIGXFSZ: return SIGXFSZ;
+#endif
+ default: return -1;
+ }
+}
+
+
+uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts) {
+ /* TODO(cjihrig): Handle overflow. */
+ return (uvwasi_timestamp_t) ts->tv_sec * NANOS_PER_SEC + ts->tv_nsec;
+}
+
+
+uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat) {
+ uint64_t mode;
+
+ mode = stat->st_mode;
+
+ if (S_ISREG(mode))
+ return UVWASI_FILETYPE_REGULAR_FILE;
+
+ if (S_ISDIR(mode))
+ return UVWASI_FILETYPE_DIRECTORY;
+
+ if (S_ISCHR(mode))
+ return UVWASI_FILETYPE_CHARACTER_DEVICE;
+
+ if (S_ISLNK(mode))
+ return UVWASI_FILETYPE_SYMBOLIC_LINK;
+
+#ifdef S_ISSOCK
+ if (S_ISSOCK(mode))
+ return UVWASI_FILETYPE_SOCKET_STREAM;
+#endif /* S_ISSOCK */
+
+#ifdef S_ISFIFO
+ if (S_ISFIFO(mode))
+ return UVWASI_FILETYPE_SOCKET_STREAM;
+#endif /* S_ISFIFO */
+
+#ifdef S_ISBLK
+ if (S_ISBLK(mode))
+ return UVWASI_FILETYPE_BLOCK_DEVICE;
+#endif /* S_ISBLK */
+
+ return UVWASI_FILETYPE_UNKNOWN;
+}
+
+
+void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) {
+ fs->st_dev = stat->st_dev;
+ fs->st_ino = stat->st_ino;
+ fs->st_nlink = stat->st_nlink;
+ fs->st_size = stat->st_size;
+ fs->st_filetype = uvwasi__stat_to_filetype(stat);
+ fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim);
+ fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim);
+ fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim);
+}
diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c
new file mode 100644
index 00000000000000..28c6dcc26104c9
--- /dev/null
+++ b/deps/uvwasi/src/uvwasi.c
@@ -0,0 +1,2239 @@
+#include
+#include
+
+#ifndef _WIN32
+# include
+# include
+# include
+# include
+# include
+# define SLASH '/'
+# define SLASH_STR "/"
+# define IS_SLASH(c) ((c) == '/')
+#else
+# define SLASH '\\'
+# define SLASH_STR "\\"
+# define IS_SLASH(c) ((c) == '/' || (c) == '\\')
+#endif /* _WIN32 */
+
+#define UVWASI__READDIR_NUM_ENTRIES 1
+
+#include "uvwasi.h"
+#include "uvwasi_alloc.h"
+#include "uv.h"
+#include "uv_mapping.h"
+#include "fd_table.h"
+#include "clocks.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
+
+static void* default_malloc(size_t size, void* mem_user_data) {
+ return malloc(size);
+}
+
+static void default_free(void* ptr, void* mem_user_data) {
+ free(ptr);
+}
+
+static void* default_calloc(size_t nmemb, size_t size, void* mem_user_data) {
+ return calloc(nmemb, size);
+}
+
+static void* default_realloc(void* ptr, size_t size, void* mem_user_data) {
+ return realloc(ptr, size);
+}
+
+void* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size) {
+ return uvwasi->allocator->malloc(size, uvwasi->allocator->mem_user_data);
+}
+
+void uvwasi__free(const uvwasi_t* uvwasi, void* ptr) {
+ uvwasi->allocator->free(ptr, uvwasi->allocator->mem_user_data);
+}
+
+void* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size) {
+ return uvwasi->allocator->calloc(nmemb,
+ size,
+ uvwasi->allocator->mem_user_data);
+}
+
+void* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size) {
+ return uvwasi->allocator->realloc(ptr,
+ size,
+ uvwasi->allocator->mem_user_data);
+}
+
+static const uvwasi_mem_t default_allocator = {
+ NULL,
+ default_malloc,
+ default_free,
+ default_calloc,
+ default_realloc,
+};
+
+
+static int uvwasi__is_absolute_path(const char* path, 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] == '/';
+}
+
+
+static 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_lookupflags_t flags) {
+ uv_fs_t realpath_req;
+ uvwasi_errno_t err;
+ char* abs_path;
+ char* tok;
+ char* ptr;
+ int realpath_size;
+ int abs_size;
+ int input_is_absolute;
+ int r;
+#ifdef _WIN32
+ int i;
+#endif /* _WIN32 */
+
+ err = UVWASI_ESUCCESS;
+ input_is_absolute = uvwasi__is_absolute_path(path, path_len);
+
+ if (1 == input_is_absolute) {
+ /* TODO(cjihrig): Revisit this. Copying is probably not necessary here. */
+ abs_size = path_len;
+ abs_path = uvwasi__malloc(uvwasi, abs_size);
+ if (abs_path == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ memcpy(abs_path, path, abs_size);
+ } else {
+ /* Resolve the relative path to fd's real path. */
+ abs_size = path_len + strlen(fd->real_path) + 2;
+ abs_path = uvwasi__malloc(uvwasi, abs_size);
+ if (abs_path == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ r = snprintf(abs_path, abs_size, "%s/%s", fd->real_path, path);
+ if (r <= 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ goto exit;
+ }
+ }
+
+#ifdef _WIN32
+ /* On Windows, convert slashes to backslashes. */
+ for (i = 0; i < abs_size; ++i) {
+ if (abs_path[i] == '/')
+ abs_path[i] = SLASH;
+ }
+#endif /* _WIN32 */
+
+ ptr = resolved_path;
+ tok = strtok(abs_path, SLASH_STR);
+ for (; tok != NULL; tok = strtok(NULL, SLASH_STR)) {
+ if (0 == strcmp(tok, "."))
+ continue;
+
+ if (0 == strcmp(tok, "..")) {
+ while (*ptr != SLASH && ptr != resolved_path)
+ ptr--;
+ *ptr = '\0';
+ continue;
+ }
+
+#ifdef _WIN32
+ /* On Windows, prevent a leading slash in the path. */
+ if (ptr == resolved_path)
+ r = sprintf(ptr, "%s", tok);
+ else
+#endif /* _WIN32 */
+ r = sprintf(ptr, "%c%s", SLASH, tok);
+
+ if (r < 1) { /* At least one character should have been written. */
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ goto exit;
+ }
+
+ ptr += r;
+ }
+
+ if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
+ r = uv_fs_realpath(NULL, &realpath_req, resolved_path, NULL);
+ if (r == 0) {
+ realpath_size = strlen(realpath_req.ptr) + 1;
+ if (realpath_size > PATH_MAX_BYTES) {
+ err = UVWASI_ENOBUFS;
+ uv_fs_req_cleanup(&realpath_req);
+ goto exit;
+ }
+
+ memcpy(resolved_path, realpath_req.ptr, realpath_size);
+ } else if (r != UV_ENOENT) {
+ /* Report errors except ENOENT. */
+ err = uvwasi__translate_uv_error(r);
+ uv_fs_req_cleanup(&realpath_req);
+ goto exit;
+ }
+
+ uv_fs_req_cleanup(&realpath_req);
+ }
+
+ /* Verify that the resolved path is still in the sandbox. */
+ if (resolved_path != strstr(resolved_path, fd->real_path)) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+
+exit:
+ uvwasi__free(uvwasi, abs_path);
+ return err;
+}
+
+
+static uvwasi_errno_t uvwasi__lseek(uv_file fd,
+ uvwasi_filedelta_t offset,
+ uvwasi_whence_t whence,
+ uvwasi_filesize_t* newoffset) {
+ int real_whence;
+
+ if (whence == UVWASI_WHENCE_CUR)
+ real_whence = SEEK_CUR;
+ else if (whence == UVWASI_WHENCE_END)
+ real_whence = SEEK_END;
+ else if (whence == UVWASI_WHENCE_SET)
+ real_whence = SEEK_SET;
+ else
+ return UVWASI_EINVAL;
+
+#ifdef _WIN32
+ int64_t r;
+
+ r = _lseeki64(fd, offset, real_whence);
+ if (-1L == r)
+ return uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+#else
+ off_t r;
+
+ r = lseek(fd, offset, real_whence);
+ if ((off_t) -1 == r)
+ return uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+#endif /* _WIN32 */
+
+ *newoffset = r;
+ return UVWASI_ESUCCESS;
+}
+
+
+static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
+ uv_buf_t** buffers,
+ const uvwasi_iovec_t* iovs,
+ size_t iovs_len) {
+ uv_buf_t* bufs;
+ size_t i;
+
+ if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
+ return UVWASI_ENOMEM;
+
+ bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs));
+ if (bufs == NULL)
+ return UVWASI_ENOMEM;
+
+ for (i = 0; i < iovs_len; ++i)
+ bufs[i] = uv_buf_init(iovs[i].buf, iovs[i].buf_len);
+
+ *buffers = bufs;
+ return UVWASI_ESUCCESS;
+}
+
+
+static uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi,
+ uv_buf_t** buffers,
+ const uvwasi_ciovec_t* iovs,
+ size_t iovs_len) {
+ uv_buf_t* bufs;
+ size_t i;
+
+ if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
+ return UVWASI_ENOMEM;
+
+ bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs));
+ if (bufs == NULL)
+ return UVWASI_ENOMEM;
+
+ for (i = 0; i < iovs_len; ++i)
+ bufs[i] = uv_buf_init((char*)iovs[i].buf, iovs[i].buf_len);
+
+ *buffers = bufs;
+ return UVWASI_ESUCCESS;
+}
+
+
+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;
+ int r;
+
+ if (uvwasi == NULL || options == NULL || options->fd_table_size == 0)
+ return UVWASI_EINVAL;
+
+ uvwasi->allocator = options->allocator;
+ if (uvwasi->allocator == NULL)
+ uvwasi->allocator = &default_allocator;
+
+ uvwasi->argv_buf = NULL;
+ uvwasi->argv = NULL;
+ uvwasi->env_buf = NULL;
+ uvwasi->env = NULL;
+ uvwasi->fds.fds = NULL;
+
+ args_size = 0;
+ for (i = 0; i < options->argc; ++i)
+ args_size += strlen(options->argv[i]) + 1;
+
+ uvwasi->argc = options->argc;
+ uvwasi->argv_buf_size = args_size;
+
+ if (args_size > 0) {
+ uvwasi->argv_buf = uvwasi__malloc(uvwasi, args_size);
+ if (uvwasi->argv_buf == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ uvwasi->argv = uvwasi__calloc(uvwasi, options->argc, sizeof(char*));
+ if (uvwasi->argv == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ offset = 0;
+ for (i = 0; i < options->argc; ++i) {
+ size = strlen(options->argv[i]) + 1;
+ memcpy(uvwasi->argv_buf + offset, options->argv[i], size);
+ uvwasi->argv[i] = uvwasi->argv_buf + offset;
+ offset += size;
+ }
+ }
+
+ env_count = 0;
+ env_buf_size = 0;
+ if (options->envp != NULL) {
+ while (options->envp[env_count] != NULL) {
+ env_buf_size += strlen(options->envp[env_count]) + 1;
+ env_count++;
+ }
+ }
+
+ uvwasi->envc = env_count;
+ uvwasi->env_buf_size = env_buf_size;
+
+ if (env_buf_size > 0) {
+ uvwasi->env_buf = uvwasi__malloc(uvwasi, env_buf_size);
+ if (uvwasi->env_buf == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ uvwasi->env = uvwasi__calloc(uvwasi, env_count, sizeof(char*));
+ if (uvwasi->env == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
+
+ offset = 0;
+ for (i = 0; i < env_count; ++i) {
+ size = strlen(options->envp[i]) + 1;
+ memcpy(uvwasi->env_buf + offset, options->envp[i], size);
+ uvwasi->env[i] = uvwasi->env_buf + offset;
+ offset += size;
+ }
+ }
+
+ for (i = 0; i < options->preopenc; ++i) {
+ if (options->preopens[i].real_path == NULL ||
+ options->preopens[i].mapped_path == NULL) {
+ err = UVWASI_EINVAL;
+ goto exit;
+ }
+ }
+
+ err = uvwasi_fd_table_init(uvwasi, &uvwasi->fds, options->fd_table_size);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ for (i = 0; i < options->preopenc; ++i) {
+ r = uv_fs_realpath(NULL,
+ &realpath_req,
+ options->preopens[i].real_path,
+ NULL);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ uv_fs_req_cleanup(&realpath_req);
+ goto exit;
+ }
+
+ r = uv_fs_open(NULL, &open_req, realpath_req.ptr, 0, 0666, NULL);
+ if (r < 0) {
+ err = uvwasi__translate_uv_error(r);
+ uv_fs_req_cleanup(&realpath_req);
+ uv_fs_req_cleanup(&open_req);
+ goto exit;
+ }
+
+ err = uvwasi_fd_table_insert_preopen(uvwasi,
+ &uvwasi->fds,
+ open_req.result,
+ options->preopens[i].mapped_path,
+ realpath_req.ptr);
+ uv_fs_req_cleanup(&realpath_req);
+ uv_fs_req_cleanup(&open_req);
+
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+ }
+
+ return UVWASI_ESUCCESS;
+
+exit:
+ uvwasi_destroy(uvwasi);
+ return err;
+}
+
+
+void uvwasi_destroy(uvwasi_t* uvwasi) {
+ if (uvwasi == NULL)
+ return;
+
+ 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->argv_buf = NULL;
+ uvwasi->argv = NULL;
+ uvwasi->env_buf = NULL;
+ uvwasi->env = NULL;
+}
+
+
+uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
+ const uvwasi_fd_t fd,
+ uv_file new_host_fd) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ wrap->fd = new_host_fd;
+ uv_mutex_unlock(&wrap->mutex);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_args_get(uvwasi_t* uvwasi, char** argv, char* argv_buf) {
+ size_t i;
+
+ if (uvwasi == NULL || argv == NULL || argv_buf == NULL)
+ return UVWASI_EINVAL;
+
+ for (i = 0; i < uvwasi->argc; ++i) {
+ argv[i] = argv_buf + (uvwasi->argv[i] - uvwasi->argv_buf);
+ }
+
+ memcpy(argv_buf, uvwasi->argv_buf, uvwasi->argv_buf_size);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_args_sizes_get(uvwasi_t* uvwasi,
+ size_t* argc,
+ size_t* argv_buf_size) {
+ if (uvwasi == NULL || argc == NULL || argv_buf_size == NULL)
+ return UVWASI_EINVAL;
+
+ *argc = uvwasi->argc;
+ *argv_buf_size = uvwasi->argv_buf_size;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_clock_res_get(uvwasi_t* uvwasi,
+ uvwasi_clockid_t clock_id,
+ uvwasi_timestamp_t* resolution) {
+ if (uvwasi == NULL || resolution == NULL)
+ return UVWASI_EINVAL;
+
+ switch (clock_id) {
+ case UVWASI_CLOCK_MONOTONIC:
+ case UVWASI_CLOCK_REALTIME:
+ *resolution = 1; /* Nanosecond precision. */
+ return UVWASI_ESUCCESS;
+ case UVWASI_CLOCK_PROCESS_CPUTIME_ID:
+ return uvwasi__clock_getres_process_cputime(resolution);
+ case UVWASI_CLOCK_THREAD_CPUTIME_ID:
+ return uvwasi__clock_getres_thread_cputime(resolution);
+ default:
+ return UVWASI_EINVAL;
+ }
+}
+
+
+uvwasi_errno_t uvwasi_clock_time_get(uvwasi_t* uvwasi,
+ uvwasi_clockid_t clock_id,
+ uvwasi_timestamp_t precision,
+ uvwasi_timestamp_t* time) {
+ if (uvwasi == NULL || time == NULL)
+ return UVWASI_EINVAL;
+
+ switch (clock_id) {
+ case UVWASI_CLOCK_MONOTONIC:
+ *time = uv_hrtime();
+ return UVWASI_ESUCCESS;
+ case UVWASI_CLOCK_REALTIME:
+ return uvwasi__clock_gettime_realtime(time);
+ case UVWASI_CLOCK_PROCESS_CPUTIME_ID:
+ return uvwasi__clock_gettime_process_cputime(time);
+ case UVWASI_CLOCK_THREAD_CPUTIME_ID:
+ return uvwasi__clock_gettime_thread_cputime(time);
+ default:
+ return UVWASI_EINVAL;
+ }
+}
+
+
+uvwasi_errno_t uvwasi_environ_get(uvwasi_t* uvwasi,
+ char** environment,
+ char* environ_buf) {
+ size_t i;
+
+ if (uvwasi == NULL || environment == NULL || environ_buf == NULL)
+ return UVWASI_EINVAL;
+
+ for (i = 0; i < uvwasi->envc; ++i) {
+ environment[i] = environ_buf + (uvwasi->env[i] - uvwasi->env_buf);
+ }
+
+ memcpy(environ_buf, uvwasi->env_buf, uvwasi->env_buf_size);
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_environ_sizes_get(uvwasi_t* uvwasi,
+ size_t* environ_count,
+ size_t* environ_buf_size) {
+ if (uvwasi == NULL || environ_count == NULL || environ_buf_size == NULL)
+ return UVWASI_EINVAL;
+
+ *environ_count = uvwasi->envc;
+ *environ_buf_size = uvwasi->env_buf_size;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t offset,
+ uvwasi_filesize_t len,
+ uvwasi_advice_t advice) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+#ifdef POSIX_FADV_NORMAL
+ int mapped_advice;
+ int r;
+#endif /* POSIX_FADV_NORMAL */
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ switch (advice) {
+ case UVWASI_ADVICE_DONTNEED:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_DONTNEED;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ case UVWASI_ADVICE_NOREUSE:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_NOREUSE;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ case UVWASI_ADVICE_NORMAL:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_NORMAL;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ case UVWASI_ADVICE_RANDOM:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_RANDOM;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ case UVWASI_ADVICE_SEQUENTIAL:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_SEQUENTIAL;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ case UVWASI_ADVICE_WILLNEED:
+#ifdef POSIX_FADV_NORMAL
+ mapped_advice = POSIX_FADV_WILLNEED;
+#endif /* POSIX_FADV_NORMAL */
+ break;
+ default:
+ return UVWASI_EINVAL;
+ }
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_ADVISE, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = UVWASI_ESUCCESS;
+
+#ifdef POSIX_FADV_NORMAL
+ r = posix_fadvise(wrap->fd, offset, len, mapped_advice);
+ if (r != 0)
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(r));
+#endif /* POSIX_FADV_NORMAL */
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t offset,
+ uvwasi_filesize_t len) {
+#if !defined(__POSIX__)
+ uv_fs_t req;
+ uint64_t st_size;
+#endif /* !__POSIX__ */
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_ALLOCATE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ /* Try to use posix_fallocate(). If that's not an option, fall back to the
+ race condition prone combination of fstat() + ftruncate(). */
+#if defined(__POSIX__)
+ r = posix_fallocate(wrap->fd, offset, len);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(r));
+ goto exit;
+ }
+#else
+ r = uv_fs_fstat(NULL, &req, wrap->fd, NULL);
+ st_size = req.statbuf.st_size;
+ uv_fs_req_cleanup(&req);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ if (st_size < offset + len) {
+ r = uv_fs_ftruncate(NULL, &req, wrap->fd, offset + len, NULL);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+ }
+#endif /* __POSIX__ */
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ r = uv_fs_close(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, fd);
+}
+
+
+uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_DATASYNC,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ r = uv_fs_fdatasync(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_fdstat_t* buf) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+#ifndef _WIN32
+ int r;
+#endif
+
+ if (uvwasi == NULL || buf == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ buf->fs_filetype = wrap->type;
+ buf->fs_rights_base = wrap->rights_base;
+ buf->fs_rights_inheriting = wrap->rights_inheriting;
+#ifdef _WIN32
+ buf->fs_flags = 0; /* TODO(cjihrig): Missing Windows support. */
+#else
+ r = fcntl(wrap->fd, F_GETFL);
+ if (r < 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+ buf->fs_flags = r;
+#endif /* _WIN32 */
+
+ uv_mutex_unlock(&wrap->mutex);
+ return UVWASI_ESUCCESS;
+}
+
+
+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. */
+ return UVWASI_ENOSYS;
+#else
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ int mapped_flags;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ mapped_flags = 0;
+
+ if ((flags & UVWASI_FDFLAG_APPEND) == UVWASI_FDFLAG_APPEND)
+ mapped_flags |= O_APPEND;
+
+ if ((flags & UVWASI_FDFLAG_DSYNC) == UVWASI_FDFLAG_DSYNC)
+#ifdef O_DSYNC
+ mapped_flags |= O_DSYNC;
+#else
+ mapped_flags |= O_SYNC;
+#endif /* O_DSYNC */
+
+ if ((flags & UVWASI_FDFLAG_NONBLOCK) == UVWASI_FDFLAG_NONBLOCK)
+ mapped_flags |= O_NONBLOCK;
+
+ if ((flags & UVWASI_FDFLAG_RSYNC) == UVWASI_FDFLAG_RSYNC)
+#ifdef O_RSYNC
+ mapped_flags |= O_RSYNC;
+#else
+ mapped_flags |= O_SYNC;
+#endif /* O_RSYNC */
+
+ if ((flags & UVWASI_FDFLAG_SYNC) == UVWASI_FDFLAG_SYNC)
+ mapped_flags |= O_SYNC;
+
+ r = fcntl(wrap->fd, F_SETFL, mapped_flags);
+ if (r < 0)
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ else
+ err = UVWASI_ESUCCESS;
+
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+#endif /* _WIN32 */
+}
+
+
+uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_rights_t fs_rights_base,
+ uvwasi_rights_t fs_rights_inheriting
+ ) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ /* Check for attempts to add new permissions. */
+ if ((fs_rights_base | wrap->rights_base) > wrap->rights_base) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+
+ if ((fs_rights_inheriting | wrap->rights_inheriting) >
+ wrap->rights_inheriting) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+
+ wrap->rights_base = fs_rights_base;
+ wrap->rights_inheriting = fs_rights_inheriting;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filestat_t* buf) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || buf == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_FILESTAT_GET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ r = uv_fs_fstat(NULL, &req, wrap->fd, NULL);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ uvwasi__stat_to_filestat(&req.statbuf, buf);
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t st_size) {
+ /* TODO(cjihrig): uv_fs_ftruncate() takes an int64_t. st_size is uint64_t. */
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_FILESTAT_SET_SIZE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ r = uv_fs_ftruncate(NULL, &req, wrap->fd, st_size, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_timestamp_t st_atim,
+ uvwasi_timestamp_t st_mtim,
+ uvwasi_fstflags_t fst_flags) {
+ /* TODO(cjihrig): libuv does not currently support nanosecond precision. */
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ if (fst_flags & ~(UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW |
+ UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) {
+ return UVWASI_EINVAL;
+ }
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_FILESTAT_SET_TIMES,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ /* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
+ r = uv_fs_futime(NULL, &req, wrap->fd, st_atim, st_mtim, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const uvwasi_iovec_t* iovs,
+ size_t iovs_len,
+ uvwasi_filesize_t offset,
+ size_t* nread) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_buf_t* bufs;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ size_t uvread;
+ int r;
+
+ if (uvwasi == NULL || iovs == NULL || nread == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_READ | UVWASI_RIGHT_FD_SEEK,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uvread = req.result;
+ uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, bufs);
+
+ if (r < 0)
+ return uvwasi__translate_uv_error(r);
+
+ *nread = uvread;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_prestat_t* buf) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+
+ if (uvwasi == NULL || buf == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ if (wrap->preopen != 1) {
+ err = UVWASI_EINVAL;
+ goto exit;
+ }
+
+ buf->pr_type = UVWASI_PREOPENTYPE_DIR;
+ buf->u.dir.pr_name_len = strlen(wrap->path) + 1;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ char* path,
+ size_t path_len) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ size_t size;
+
+ if (uvwasi == NULL || path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ if (wrap->preopen != 1) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+
+ size = strlen(wrap->path) + 1;
+ if (size > path_len) {
+ err = UVWASI_ENOBUFS;
+ goto exit;
+ }
+
+ memcpy(path, wrap->path, size);
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const uvwasi_ciovec_t* iovs,
+ size_t iovs_len,
+ uvwasi_filesize_t offset,
+ size_t* nwritten) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_buf_t* bufs;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ size_t uvwritten;
+ int r;
+
+ if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_WRITE | UVWASI_RIGHT_FD_SEEK,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uvwritten = req.result;
+ uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, bufs);
+
+ if (r < 0)
+ return uvwasi__translate_uv_error(r);
+
+ *nwritten = uvwritten;
+ return UVWASI_ESUCCESS;
+}
+
+
+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) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_buf_t* bufs;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ size_t uvread;
+ int r;
+
+ if (uvwasi == NULL || iovs == NULL || nread == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uvread = req.result;
+ uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, bufs);
+
+ if (r < 0)
+ return uvwasi__translate_uv_error(r);
+
+ *nread = uvread;
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ void* buf,
+ size_t buf_len,
+ uvwasi_dircookie_t cookie,
+ 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;
+ uvwasi_dirent_t dirent;
+ uv_dirent_t dirents[UVWASI__READDIR_NUM_ENTRIES];
+ uv_dir_t* dir;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ size_t name_len;
+ size_t available;
+ size_t size_to_cp;
+ long tell;
+ int i;
+ int r;
+
+ if (uvwasi == NULL || buf == NULL || bufused == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_READDIR,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ /* Open the directory. */
+ r = uv_fs_opendir(NULL, &req, wrap->real_path, NULL);
+ if (r != 0) {
+ uv_mutex_unlock(&wrap->mutex);
+ return uvwasi__translate_uv_error(r);
+ }
+
+ /* Setup for reading the directory. */
+ dir = req.ptr;
+ dir->dirents = dirents;
+ dir->nentries = UVWASI__READDIR_NUM_ENTRIES;
+ uv_fs_req_cleanup(&req);
+
+#ifndef _WIN32
+ /* TODO(cjihrig): Need a Windows equivalent of this logic. */
+ /* Seek to the proper location in the directory. */
+ if (cookie != UVWASI_DIRCOOKIE_START)
+ seekdir(dir->dir, cookie);
+#endif
+
+ /* Read the directory entries into the provided buffer. */
+ err = UVWASI_ESUCCESS;
+ *bufused = 0;
+ while (0 != (r = uv_fs_readdir(NULL, &req, dir, NULL))) {
+ if (r < 0) {
+ err = uvwasi__translate_uv_error(r);
+ uv_fs_req_cleanup(&req);
+ goto exit;
+ }
+
+ for (i = 0; i < r; i++) {
+ /* TODO(cjihrig): This should probably be serialized to the buffer
+ consistently across platforms. In other words, d_next should always
+ be 8 bytes, d_ino should always be 8 bytes, d_namlen should always be
+ 4 bytes, and d_type should always be 1 byte. */
+#ifndef _WIN32
+ tell = telldir(dir->dir);
+ if (tell < 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ uv_fs_req_cleanup(&req);
+ goto exit;
+ }
+#else
+ tell = 0; /* TODO(cjihrig): Need to support Windows. */
+#endif /* _WIN32 */
+
+ name_len = strlen(dirents[i].name);
+ dirent.d_next = (uvwasi_dircookie_t) tell;
+ /* TODO(cjihrig): Missing ino libuv (and Windows) support. fstat()? */
+ dirent.d_ino = 0;
+ dirent.d_namlen = name_len;
+
+ switch (dirents[i].type) {
+ case UV_DIRENT_FILE:
+ dirent.d_type = UVWASI_FILETYPE_REGULAR_FILE;
+ break;
+ case UV_DIRENT_DIR:
+ dirent.d_type = UVWASI_FILETYPE_DIRECTORY;
+ break;
+ case UV_DIRENT_SOCKET:
+ dirent.d_type = UVWASI_FILETYPE_SOCKET_STREAM;
+ break;
+ case UV_DIRENT_LINK:
+ dirent.d_type = UVWASI_FILETYPE_SYMBOLIC_LINK;
+ break;
+ case UV_DIRENT_CHAR:
+ dirent.d_type = UVWASI_FILETYPE_CHARACTER_DEVICE;
+ break;
+ case UV_DIRENT_BLOCK:
+ dirent.d_type = UVWASI_FILETYPE_BLOCK_DEVICE;
+ break;
+ case UV_DIRENT_FIFO:
+ case UV_DIRENT_UNKNOWN:
+ default:
+ dirent.d_type = UVWASI_FILETYPE_UNKNOWN;
+ break;
+ }
+
+ /* Write dirent to the buffer. */
+ available = buf_len - *bufused;
+ size_to_cp = sizeof(dirent) > available ? available : sizeof(dirent);
+ memcpy((char*)buf + *bufused, &dirent, size_to_cp);
+ *bufused += size_to_cp;
+ /* Write the entry name to the buffer. */
+ available = buf_len - *bufused;
+ size_to_cp = name_len > available ? available : name_len;
+ memcpy((char*)buf + *bufused, &dirents[i].name, size_to_cp);
+ *bufused += size_to_cp;
+ }
+
+ uv_fs_req_cleanup(&req);
+
+ if (*bufused >= buf_len)
+ break;
+ }
+
+exit:
+ /* Close the directory. */
+ r = uv_fs_closedir(NULL, &req, dir, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
+ uvwasi_fd_t from,
+ uvwasi_fd_t to) {
+ struct uvwasi_fd_wrap_t* to_wrap;
+ struct uvwasi_fd_wrap_t* from_wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ if (from == to)
+ return UVWASI_ESUCCESS;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, from, &from_wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, to, &to_wrap, 0, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&from_wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_close(NULL, &req, to_wrap->fd, NULL);
+ uv_fs_req_cleanup(&req);
+ if (r != 0) {
+ uv_mutex_unlock(&from_wrap->mutex);
+ uv_mutex_unlock(&to_wrap->mutex);
+ return uvwasi__translate_uv_error(r);
+ }
+
+ memcpy(to_wrap, from_wrap, sizeof(*to_wrap));
+ to_wrap->id = to;
+ uv_mutex_unlock(&from_wrap->mutex);
+ uv_mutex_unlock(&to_wrap->mutex);
+ return uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, from);
+}
+
+
+uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filedelta_t offset,
+ uvwasi_whence_t whence,
+ uvwasi_filesize_t* newoffset) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+
+ if (uvwasi == NULL || newoffset == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_SEEK, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__lseek(wrap->fd, offset, whence, newoffset);
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_FD_SYNC,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ r = uv_fs_fsync(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ uvwasi_filesize_t* offset) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+
+ if (uvwasi == NULL || offset == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_TELL, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__lseek(wrap->fd, 0, UVWASI_WHENCE_CUR, offset);
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+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) {
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_buf_t* bufs;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ size_t uvwritten;
+ int r;
+
+ if (uvwasi == NULL || iovs == NULL || nwritten == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uvwritten = req.result;
+ uv_fs_req_cleanup(&req);
+ uvwasi__free(uvwasi, bufs);
+
+ if (r < 0)
+ return uvwasi__translate_uv_error(r);
+
+ *nwritten = uvwritten;
+ return UVWASI_ESUCCESS;
+}
+
+
+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];
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_CREATE_DIRECTORY,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ 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);
+
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+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_filestat_t* buf) {
+ char resolved_path[PATH_MAX_BYTES];
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || path == NULL || buf == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_FILESTAT_GET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
+ path,
+ path_len,
+ resolved_path,
+ flags);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ r = uv_fs_stat(NULL, &req, resolved_path, NULL);
+ if (r != 0) {
+ uv_fs_req_cleanup(&req);
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ uvwasi__stat_to_filestat(&req.statbuf, buf);
+ uv_fs_req_cleanup(&req);
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+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_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];
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || path == NULL)
+ return UVWASI_EINVAL;
+
+ if (fst_flags & ~(UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW |
+ UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) {
+ return UVWASI_EINVAL;
+ }
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
+ path,
+ path_len,
+ 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);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+}
+
+
+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_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];
+ struct uvwasi_fd_wrap_t* old_wrap;
+ struct uvwasi_fd_wrap_t* new_wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int r;
+
+ if (uvwasi == NULL || old_path == NULL || new_path == NULL)
+ return UVWASI_EINVAL;
+
+ if (old_fd == new_fd) {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_LINK_SOURCE |
+ UVWASI_RIGHT_PATH_LINK_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ new_wrap = old_wrap;
+ } else {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_LINK_SOURCE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ new_fd,
+ &new_wrap,
+ UVWASI_RIGHT_PATH_LINK_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&old_wrap->mutex);
+ return err;
+ }
+ }
+
+ err = uvwasi__resolve_path(uvwasi,
+ old_wrap,
+ old_path,
+ old_path_len,
+ resolved_old_path,
+ old_flags);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ err = uvwasi__resolve_path(uvwasi,
+ new_wrap,
+ new_path,
+ new_path_len,
+ resolved_new_path,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ r = uv_fs_link(NULL, &req, resolved_old_path, resolved_new_path, NULL);
+ uv_fs_req_cleanup(&req);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&old_wrap->mutex);
+ if (old_fd != new_fd)
+ uv_mutex_unlock(&new_wrap->mutex);
+ return err;
+}
+
+
+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_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];
+ uvwasi_rights_t needed_inheriting;
+ uvwasi_rights_t needed_base;
+ struct uvwasi_fd_wrap_t* dirfd_wrap;
+ struct uvwasi_fd_wrap_t wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int flags;
+ int read;
+ int write;
+ int r;
+
+ if (uvwasi == NULL || path == NULL || fd == NULL)
+ return UVWASI_EINVAL;
+
+ read = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_READ |
+ UVWASI_RIGHT_FD_READDIR));
+ write = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_DATASYNC |
+ UVWASI_RIGHT_FD_WRITE |
+ UVWASI_RIGHT_FD_ALLOCATE |
+ UVWASI_RIGHT_FD_FILESTAT_SET_SIZE));
+ flags = write ? read ? UV_FS_O_RDWR : UV_FS_O_WRONLY : UV_FS_O_RDONLY;
+ needed_base = UVWASI_RIGHT_PATH_OPEN;
+ needed_inheriting = fs_rights_base | fs_rights_inheriting;
+
+ if ((o_flags & UVWASI_O_CREAT) != 0) {
+ flags |= UV_FS_O_CREAT;
+ needed_base |= UVWASI_RIGHT_PATH_CREATE_FILE;
+ }
+ if ((o_flags & UVWASI_O_DIRECTORY) != 0)
+ flags |= UV_FS_O_DIRECTORY;
+ if ((o_flags & UVWASI_O_EXCL) != 0)
+ flags |= UV_FS_O_EXCL;
+ if ((o_flags & UVWASI_O_TRUNC) != 0) {
+ flags |= UV_FS_O_TRUNC;
+ needed_base |= UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE;
+ }
+
+ if ((fs_flags & UVWASI_FDFLAG_APPEND) != 0)
+ flags |= UV_FS_O_APPEND;
+ if ((fs_flags & UVWASI_FDFLAG_DSYNC) != 0) {
+ flags |= UV_FS_O_DSYNC;
+ needed_inheriting |= UVWASI_RIGHT_FD_DATASYNC;
+ }
+ if ((fs_flags & UVWASI_FDFLAG_NONBLOCK) != 0)
+ flags |= UV_FS_O_NONBLOCK;
+ if ((fs_flags & UVWASI_FDFLAG_RSYNC) != 0) {
+#ifdef O_RSYNC
+ flags |= O_RSYNC; /* libuv has no UV_FS_O_RSYNC. */
+#else
+ flags |= UV_FS_O_SYNC;
+#endif
+ needed_inheriting |= UVWASI_RIGHT_FD_SYNC;
+ }
+ if ((fs_flags & UVWASI_FDFLAG_SYNC) != 0) {
+ flags |= UV_FS_O_SYNC;
+ needed_inheriting |= UVWASI_RIGHT_FD_SYNC;
+ }
+ 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,
+ dirfd,
+ &dirfd_wrap,
+ needed_base,
+ needed_inheriting);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi,
+ dirfd_wrap,
+ path,
+ path_len,
+ resolved_path,
+ dirflags);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_open(NULL, &req, resolved_path, flags, 0666, NULL);
+ uv_fs_req_cleanup(&req);
+
+ if (r < 0) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
+ return uvwasi__translate_uv_error(r);
+ }
+
+ err = uvwasi_fd_table_insert_fd(uvwasi,
+ &uvwasi->fds,
+ r,
+ flags,
+ resolved_path,
+ fs_rights_base,
+ fs_rights_inheriting,
+ &wrap);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
+ goto close_file_and_error_exit;
+ }
+
+ /* Not all platforms support UV_FS_O_DIRECTORY, so enforce it here as well. */
+ if ((o_flags & UVWASI_O_DIRECTORY) != 0 &&
+ wrap.type != UVWASI_FILETYPE_DIRECTORY) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
+ uvwasi_fd_table_remove(uvwasi, &uvwasi->fds, wrap.id);
+ err = UVWASI_ENOTDIR;
+ goto close_file_and_error_exit;
+ }
+
+ *fd = wrap.id;
+ uv_mutex_unlock(&dirfd_wrap->mutex);
+ return UVWASI_ESUCCESS;
+
+close_file_and_error_exit:
+ uv_fs_close(NULL, &req, r, NULL);
+ uv_fs_req_cleanup(&req);
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
+ uvwasi_fd_t fd,
+ const char* path,
+ size_t path_len,
+ char* buf,
+ size_t buf_len,
+ size_t* bufused) {
+ char resolved_path[PATH_MAX_BYTES];
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ size_t len;
+ int r;
+
+ if (uvwasi == NULL || path == NULL || buf == NULL || bufused == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_READLINK,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_readlink(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ if (r != 0) {
+ uv_fs_req_cleanup(&req);
+ return uvwasi__translate_uv_error(r);
+ }
+
+ len = strnlen(req.ptr, buf_len);
+ if (len >= buf_len) {
+ uv_fs_req_cleanup(&req);
+ return UVWASI_ENOBUFS;
+ }
+
+ memcpy(buf, req.ptr, len);
+ buf[len] = '\0';
+ *bufused = len + 1;
+ uv_fs_req_cleanup(&req);
+ return UVWASI_ESUCCESS;
+}
+
+
+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];
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_REMOVE_DIRECTORY,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_rmdir(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
+ uvwasi_fd_t old_fd,
+ const char* old_path,
+ 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];
+ struct uvwasi_fd_wrap_t* old_wrap;
+ struct uvwasi_fd_wrap_t* new_wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int r;
+
+ if (uvwasi == NULL || old_path == NULL || new_path == NULL)
+ return UVWASI_EINVAL;
+
+ if (old_fd == new_fd) {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_RENAME_SOURCE |
+ UVWASI_RIGHT_PATH_RENAME_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ new_wrap = old_wrap;
+ } else {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_RENAME_SOURCE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ new_fd,
+ &new_wrap,
+ UVWASI_RIGHT_PATH_RENAME_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&old_wrap->mutex);
+ return err;
+ }
+ }
+
+ err = uvwasi__resolve_path(uvwasi,
+ old_wrap,
+ old_path,
+ old_path_len,
+ resolved_old_path,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ err = uvwasi__resolve_path(uvwasi,
+ new_wrap,
+ new_path,
+ new_path_len,
+ resolved_new_path,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ goto exit;
+
+ r = uv_fs_rename(NULL, &req, resolved_old_path, resolved_new_path, NULL);
+ uv_fs_req_cleanup(&req);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&old_wrap->mutex);
+ if (old_fd != new_fd)
+ uv_mutex_unlock(&new_wrap->mutex);
+
+ return err;
+}
+
+
+uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
+ const char* old_path,
+ 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];
+ struct uvwasi_fd_wrap_t* wrap;
+ uvwasi_errno_t err;
+ uv_fs_t req;
+ int r;
+
+ if (uvwasi == NULL || old_path == NULL || new_path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_SYMLINK,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
+ new_path,
+ new_path_len,
+ resolved_new_path,
+ 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ /* 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);
+ uv_fs_req_cleanup(&req);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+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];
+ struct uvwasi_fd_wrap_t* wrap;
+ uv_fs_t req;
+ uvwasi_errno_t err;
+ int r;
+
+ if (uvwasi == NULL || path == NULL)
+ return UVWASI_EINVAL;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ fd,
+ &wrap,
+ UVWASI_RIGHT_PATH_UNLINK_FILE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
+
+ r = uv_fs_unlink(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
+ uv_fs_req_cleanup(&req);
+
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+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_errno_t uvwasi_proc_exit(uvwasi_t* uvwasi, uvwasi_exitcode_t rval) {
+ exit(rval);
+ return UVWASI_ESUCCESS; /* This doesn't happen. */
+}
+
+
+uvwasi_errno_t uvwasi_proc_raise(uvwasi_t* uvwasi, uvwasi_signal_t sig) {
+ int r;
+
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+ r = uvwasi__translate_to_uv_signal(sig);
+ if (r == -1)
+ return UVWASI_ENOSYS;
+
+ r = uv_kill(uv_os_getpid(), r);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_random_get(uvwasi_t* uvwasi, void* buf, size_t buf_len) {
+ int r;
+
+ if (uvwasi == NULL || buf == NULL)
+ return UVWASI_EINVAL;
+
+ r = uv_random(NULL, NULL, buf, buf_len, 0, NULL);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
+ return UVWASI_ESUCCESS;
+}
+
+
+uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) {
+ if (uvwasi == NULL)
+ return UVWASI_EINVAL;
+
+#ifndef _WIN32
+ if (0 != sched_yield())
+ return uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+#else
+ SwitchToThread();
+#endif /* _WIN32 */
+
+ return UVWASI_ESUCCESS;
+}
+
+
+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_riflags_t ri_flags,
+ size_t* ro_datalen,
+ uvwasi_roflags_t* ro_flags) {
+ /* TODO(cjihrig): Waiting to implement, pending
+ https://github.com/WebAssembly/WASI/issues/4 */
+ return UVWASI_ENOTSUP;
+}
+
+
+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_siflags_t si_flags,
+ size_t* so_datalen) {
+ /* TODO(cjihrig): Waiting to implement, pending
+ https://github.com/WebAssembly/WASI/issues/4 */
+ return UVWASI_ENOTSUP;
+}
+
+
+uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
+ uvwasi_fd_t sock,
+ uvwasi_sdflags_t how) {
+ /* TODO(cjihrig): Waiting to implement, pending
+ https://github.com/WebAssembly/WASI/issues/4 */
+ return UVWASI_ENOTSUP;
+}
+
+
+const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code) {
+ switch (code) {
+#define V(errcode) case errcode: return #errcode;
+ V(UVWASI_E2BIG)
+ V(UVWASI_EACCES)
+ V(UVWASI_EADDRINUSE)
+ V(UVWASI_EADDRNOTAVAIL)
+ V(UVWASI_EAFNOSUPPORT)
+ V(UVWASI_EAGAIN)
+ V(UVWASI_EALREADY)
+ V(UVWASI_EBADF)
+ V(UVWASI_EBADMSG)
+ V(UVWASI_EBUSY)
+ V(UVWASI_ECANCELED)
+ V(UVWASI_ECHILD)
+ V(UVWASI_ECONNABORTED)
+ V(UVWASI_ECONNREFUSED)
+ V(UVWASI_ECONNRESET)
+ V(UVWASI_EDEADLK)
+ V(UVWASI_EDESTADDRREQ)
+ V(UVWASI_EDOM)
+ V(UVWASI_EDQUOT)
+ V(UVWASI_EEXIST)
+ V(UVWASI_EFAULT)
+ V(UVWASI_EFBIG)
+ V(UVWASI_EHOSTUNREACH)
+ V(UVWASI_EIDRM)
+ V(UVWASI_EILSEQ)
+ V(UVWASI_EINPROGRESS)
+ V(UVWASI_EINTR)
+ V(UVWASI_EINVAL)
+ V(UVWASI_EIO)
+ V(UVWASI_EISCONN)
+ V(UVWASI_EISDIR)
+ V(UVWASI_ELOOP)
+ V(UVWASI_EMFILE)
+ V(UVWASI_EMLINK)
+ V(UVWASI_EMSGSIZE)
+ V(UVWASI_EMULTIHOP)
+ V(UVWASI_ENAMETOOLONG)
+ V(UVWASI_ENETDOWN)
+ V(UVWASI_ENETRESET)
+ V(UVWASI_ENETUNREACH)
+ V(UVWASI_ENFILE)
+ V(UVWASI_ENOBUFS)
+ V(UVWASI_ENODEV)
+ V(UVWASI_ENOENT)
+ V(UVWASI_ENOEXEC)
+ V(UVWASI_ENOLCK)
+ V(UVWASI_ENOLINK)
+ V(UVWASI_ENOMEM)
+ V(UVWASI_ENOMSG)
+ V(UVWASI_ENOPROTOOPT)
+ V(UVWASI_ENOSPC)
+ V(UVWASI_ENOSYS)
+ V(UVWASI_ENOTCONN)
+ V(UVWASI_ENOTDIR)
+ V(UVWASI_ENOTEMPTY)
+ V(UVWASI_ENOTRECOVERABLE)
+ V(UVWASI_ENOTSOCK)
+ V(UVWASI_ENOTSUP)
+ V(UVWASI_ENOTTY)
+ V(UVWASI_ENXIO)
+ V(UVWASI_EOVERFLOW)
+ V(UVWASI_EOWNERDEAD)
+ V(UVWASI_EPERM)
+ V(UVWASI_EPIPE)
+ V(UVWASI_EPROTO)
+ V(UVWASI_EPROTONOSUPPORT)
+ V(UVWASI_EPROTOTYPE)
+ V(UVWASI_ERANGE)
+ V(UVWASI_EROFS)
+ V(UVWASI_ESPIPE)
+ V(UVWASI_ESRCH)
+ V(UVWASI_ESTALE)
+ V(UVWASI_ETIMEDOUT)
+ V(UVWASI_ETXTBSY)
+ V(UVWASI_EXDEV)
+ V(UVWASI_ENOTCAPABLE)
+ V(UVWASI_ESUCCESS)
+#undef V
+ default:
+ return "UVWASI_UNKNOWN_ERROR";
+ }
+}
diff --git a/deps/uvwasi/src/uvwasi_alloc.h b/deps/uvwasi/src/uvwasi_alloc.h
new file mode 100644
index 00000000000000..1486f313911b01
--- /dev/null
+++ b/deps/uvwasi/src/uvwasi_alloc.h
@@ -0,0 +1,11 @@
+#ifndef __UVWASI_ALLOC_H__
+#define __UVWASI_ALLOC_H__
+
+#include "uvwasi.h"
+
+void* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size);
+void uvwasi__free(const uvwasi_t* uvwasi, void* ptr);
+void* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size);
+void* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size);
+
+#endif
diff --git a/deps/uvwasi/uvwasi.gyp b/deps/uvwasi/uvwasi.gyp
new file mode 100644
index 00000000000000..c07b07b608b724
--- /dev/null
+++ b/deps/uvwasi/uvwasi.gyp
@@ -0,0 +1,25 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'uvwasi',
+ 'type': 'static_library',
+ 'cflags': ['-fvisibility=hidden'],
+ 'xcode_settings': {
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
+ },
+ 'include_dirs': ['include'],
+ 'sources': [
+ 'src/clocks.c',
+ 'src/fd_table.c',
+ 'src/uv_mapping.c',
+ 'src/uvwasi.c',
+ ],
+ 'dependencies': [
+ '../uv/uv.gyp:libuv',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': ['include']
+ },
+ }
+ ]
+}
diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore
index ce47fa36103f45..6a9bbd67997311 100644
--- a/deps/v8/.gitignore
+++ b/deps/v8/.gitignore
@@ -52,6 +52,8 @@
/test/test262/data
/test/test262/harness
/test/wasm-js/data
+/test/wasm-js/tests
+/test/wasm-js/tests.tar.gz
/test/wasm-spec-tests/tests
/test/wasm-spec-tests/tests.tar.gz
/third_party/*
diff --git a/deps/v8/.gn b/deps/v8/.gn
index 328778fb46bcdf..d4ad959954845f 100644
--- a/deps/v8/.gn
+++ b/deps/v8/.gn
@@ -16,4 +16,5 @@ check_targets = []
# These are the list of GN files that run exec_script. This whitelist exists
# to force additional review for new uses of exec_script, which is strongly
# discouraged except for gypi_to_gn calls.
-exec_script_whitelist = build_dotfile_settings.exec_script_whitelist + []
+exec_script_whitelist = build_dotfile_settings.exec_script_whitelist +
+ [ "//build_overrides/build.gni" ]
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS
index 827d124b0dcf0d..1198de8f358fbc 100644
--- a/deps/v8/AUTHORS
+++ b/deps/v8/AUTHORS
@@ -39,6 +39,7 @@ Vewd Software AS <*@vewd.com>
Groupon <*@groupon.com>
Meteor Development Group <*@meteor.com>
Cloudflare, Inc. <*@cloudflare.com>
+Julia Computing, Inc. <*@juliacomputing.com>
Aaron Bieber
Abdulla Kamar
@@ -74,6 +75,7 @@ Colin Ihrig
Daniel Andersson
Daniel Bevenius
Daniel James
+David Carlier
Deepak Mohan
Deon Dior
Dominic Farolini
@@ -163,6 +165,7 @@ Rob Wu
Robert Meijer
Robert Mustacchi
Robert Nagy
+Rong Wang
Ross Kirsling
Ruben Bridgewater
Ryan Dahl
diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn
index efca4a626f1633..90ec4097d7a2b8 100644
--- a/deps/v8/BUILD.gn
+++ b/deps/v8/BUILD.gn
@@ -91,7 +91,7 @@ declare_args() {
# Enable embedded builtins.
v8_enable_embedded_builtins = true
- # Enable the registration of unwinding info for Windows/x64.
+ # Enable the registration of unwinding info for Windows x64 and ARM64.
v8_win64_unwinding_info = true
# Enable code comments for builtins in the snapshot (impacts performance).
@@ -187,15 +187,21 @@ declare_args() {
# Enable sharing read-only space across isolates.
# Sets -DV8_SHARED_RO_HEAP.
v8_enable_shared_ro_heap = ""
-}
-# We reuse the snapshot toolchain for building torque and other generators to
-# avoid building v8_libbase on the host more than once. On mips with big endian,
-# the snapshot toolchain is the target toolchain and, hence, can't be used.
-v8_generator_toolchain = v8_snapshot_toolchain
-if (host_cpu == "x64" &&
- (v8_current_cpu == "mips" || v8_current_cpu == "mips64")) {
- v8_generator_toolchain = "//build/toolchain/linux:clang_x64"
+ # Enable lazy source positions by default.
+ v8_enable_lazy_source_positions = true
+
+ # Disable write barriers when GCs are non-incremental and
+ # heap has single generation.
+ v8_disable_write_barriers = false
+
+ # Redirect allocation in young generation so that there will be
+ # only one single generation.
+ v8_enable_single_generation = ""
+
+ # Use token threaded dispatch for the regular expression interpreter.
+ # Use switch-based dispatch if this is false
+ v8_enable_regexp_interpreter_threaded_dispatch = true
}
# Derived defaults.
@@ -231,6 +237,13 @@ if (v8_enable_fast_torque == "") {
v8_enable_fast_torque = v8_enable_fast_mksnapshot
}
+if (v8_enable_single_generation == "") {
+ v8_enable_single_generation = v8_disable_write_barriers
+}
+
+assert(!v8_disable_write_barriers || v8_enable_single_generation,
+ "Disabling write barriers works only with single generation")
+
assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations,
"Untrusted code mitigations are unsupported on ia32")
@@ -424,12 +437,21 @@ config("features") {
defines += [ "V8_SNAPSHOT_NATIVE_CODE_COUNTERS" ]
}
}
+ if (v8_enable_single_generation) {
+ defines += [ "V8_ENABLE_SINGLE_GENERATION" ]
+ }
+ if (v8_disable_write_barriers) {
+ defines += [ "V8_DISABLE_WRITE_BARRIERS" ]
+ }
if (v8_use_external_startup_data) {
defines += [ "V8_USE_EXTERNAL_STARTUP_DATA" ]
}
if (v8_enable_concurrent_marking) {
defines += [ "V8_CONCURRENT_MARKING" ]
}
+ if (v8_enable_lazy_source_positions) {
+ defines += [ "V8_ENABLE_LAZY_SOURCE_POSITIONS" ]
+ }
if (v8_check_microtasks_scopes_consistency) {
defines += [ "V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY" ]
}
@@ -451,6 +473,9 @@ config("features") {
if (v8_win64_unwinding_info) {
defines += [ "V8_WIN64_UNWINDING_INFO" ]
}
+ if (v8_enable_regexp_interpreter_threaded_dispatch) {
+ defines += [ "V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH" ]
+ }
}
config("toolchain") {
@@ -870,6 +895,8 @@ action("postmortem-metadata") {
"src/objects/code.h",
"src/objects/data-handler.h",
"src/objects/data-handler-inl.h",
+ "src/objects/descriptor-array.h",
+ "src/objects/descriptor-array-inl.h",
"src/objects/feedback-cell.h",
"src/objects/feedback-cell-inl.h",
"src/objects/fixed-array-inl.h",
@@ -968,16 +995,21 @@ torque_files = [
"src/builtins/proxy-set-prototype-of.tq",
"src/builtins/proxy.tq",
"src/builtins/reflect.tq",
+ "src/builtins/regexp-match.tq",
"src/builtins/regexp-replace.tq",
+ "src/builtins/regexp-source.tq",
+ "src/builtins/regexp-test.tq",
"src/builtins/regexp.tq",
"src/builtins/string.tq",
"src/builtins/string-endswith.tq",
"src/builtins/string-html.tq",
"src/builtins/string-iterator.tq",
+ "src/builtins/string-pad.tq",
"src/builtins/string-repeat.tq",
"src/builtins/string-slice.tq",
"src/builtins/string-startswith.tq",
"src/builtins/string-substring.tq",
+ "src/builtins/torque-internal.tq",
"src/builtins/typed-array-createtypedarray.tq",
"src/builtins/typed-array-every.tq",
"src/builtins/typed-array-filter.tq",
@@ -1002,6 +1034,7 @@ if (!v8_enable_i18n_support) {
action("run_torque") {
visibility = [
":*",
+ "tools/debug_helper/:*",
"tools/gcmole/:*",
"test/cctest/:*",
]
@@ -1023,6 +1056,8 @@ action("run_torque") {
"$target_gen_dir/torque-generated/class-definitions-tq.cc",
"$target_gen_dir/torque-generated/class-definitions-tq-inl.h",
"$target_gen_dir/torque-generated/class-definitions-tq.h",
+ "$target_gen_dir/torque-generated/class-debug-readers-tq.cc",
+ "$target_gen_dir/torque-generated/class-debug-readers-tq.h",
"$target_gen_dir/torque-generated/exported-macros-assembler-tq.cc",
"$target_gen_dir/torque-generated/exported-macros-assembler-tq.h",
"$target_gen_dir/torque-generated/csa-types-tq.h",
@@ -1752,6 +1787,8 @@ v8_compiler_sources = [
"src/compiler/escape-analysis-reducer.h",
"src/compiler/escape-analysis.cc",
"src/compiler/escape-analysis.h",
+ "src/compiler/feedback-source.cc",
+ "src/compiler/feedback-source.h",
"src/compiler/frame-states.cc",
"src/compiler/frame-states.h",
"src/compiler/frame.cc",
@@ -1892,8 +1929,6 @@ v8_compiler_sources = [
"src/compiler/types.h",
"src/compiler/value-numbering-reducer.cc",
"src/compiler/value-numbering-reducer.h",
- "src/compiler/vector-slot-pair.cc",
- "src/compiler/vector-slot-pair.h",
"src/compiler/verifier.cc",
"src/compiler/verifier.h",
"src/compiler/wasm-compiler.cc",
@@ -2031,7 +2066,6 @@ v8_source_set("v8_base_without_compiler") {
"src/builtins/builtins-internal.cc",
"src/builtins/builtins-intl.cc",
"src/builtins/builtins-json.cc",
- "src/builtins/builtins-math.cc",
"src/builtins/builtins-number.cc",
"src/builtins/builtins-object.cc",
"src/builtins/builtins-promise.cc",
@@ -2095,6 +2129,7 @@ v8_source_set("v8_base_without_compiler") {
"src/codegen/register-arch.h",
"src/codegen/register-configuration.cc",
"src/codegen/register-configuration.h",
+ "src/codegen/register.cc",
"src/codegen/register.h",
"src/codegen/reglist.h",
"src/codegen/reloc-info.cc",
@@ -2117,6 +2152,7 @@ v8_source_set("v8_base_without_compiler") {
"src/common/assert-scope.cc",
"src/common/assert-scope.h",
"src/common/checks.h",
+ "src/common/message-template.h",
"src/common/ptr-compr-inl.h",
"src/common/ptr-compr.h",
"src/compiler-dispatcher/compiler-dispatcher.cc",
@@ -2189,11 +2225,13 @@ v8_source_set("v8_base_without_compiler") {
"src/execution/isolate-utils.h",
"src/execution/isolate.cc",
"src/execution/isolate.h",
- "src/execution/message-template.h",
"src/execution/messages.cc",
"src/execution/messages.h",
"src/execution/microtask-queue.cc",
"src/execution/microtask-queue.h",
+ "src/execution/protectors-inl.h",
+ "src/execution/protectors.cc",
+ "src/execution/protectors.h",
"src/execution/runtime-profiler.cc",
"src/execution/runtime-profiler.h",
"src/execution/simulator-base.cc",
@@ -2758,7 +2796,6 @@ v8_source_set("v8_base_without_compiler") {
"src/runtime/runtime-typedarray.cc",
"src/runtime/runtime-utils.h",
"src/runtime/runtime-wasm.cc",
- "src/runtime/runtime-weak-refs.cc",
"src/runtime/runtime.cc",
"src/runtime/runtime.h",
"src/sanitizer/asan.h",
@@ -2922,6 +2959,8 @@ v8_source_set("v8_base_without_compiler") {
"src/wasm/wasm-memory.h",
"src/wasm/wasm-module-builder.cc",
"src/wasm/wasm-module-builder.h",
+ "src/wasm/wasm-module-sourcemap.cc",
+ "src/wasm/wasm-module-sourcemap.h",
"src/wasm/wasm-module.cc",
"src/wasm/wasm-module.h",
"src/wasm/wasm-objects-inl.h",
@@ -3109,6 +3148,7 @@ v8_source_set("v8_base_without_compiler") {
"src/diagnostics/arm64/eh-frame-arm64.cc",
"src/execution/arm64/frame-constants-arm64.cc",
"src/execution/arm64/frame-constants-arm64.h",
+ "src/execution/arm64/pointer-auth-arm64.cc",
"src/execution/arm64/simulator-arm64.cc",
"src/execution/arm64/simulator-arm64.h",
"src/execution/arm64/simulator-logic-arm64.cc",
@@ -3116,6 +3156,12 @@ v8_source_set("v8_base_without_compiler") {
"src/regexp/arm64/regexp-macro-assembler-arm64.h",
"src/wasm/baseline/arm64/liftoff-assembler-arm64.h",
]
+ if (is_win) {
+ sources += [
+ "src/diagnostics/unwinding-info-win64.cc",
+ "src/diagnostics/unwinding-info-win64.h",
+ ]
+ }
jumbo_excluded_sources += [
# TODO(mostynb@vewd.com): fix this code so it doesn't need
# to be excluded, see the comments inside.
@@ -3325,6 +3371,7 @@ v8_source_set("torque_base") {
"src/torque/ast.h",
"src/torque/cfg.cc",
"src/torque/cfg.h",
+ "src/torque/class-debug-reader-generator.cc",
"src/torque/constants.h",
"src/torque/contextual.h",
"src/torque/csa-generator.cc",
@@ -3351,6 +3398,8 @@ v8_source_set("torque_base") {
"src/torque/torque-compiler.h",
"src/torque/torque-parser.cc",
"src/torque/torque-parser.h",
+ "src/torque/type-inference.cc",
+ "src/torque/type-inference.h",
"src/torque/type-oracle.cc",
"src/torque/type-oracle.h",
"src/torque/type-visitor.cc",
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index 27afc18a5117cd..be6a58859c5394 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/ChangeLog
@@ -1,3 +1,1453 @@
+2019-09-04: Version 7.8.279
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.278
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.277
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.276
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.275
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.274
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.273
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.272
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.271
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-04: Version 7.8.270
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.269
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.268
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.267
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.266
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.265
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.264
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.263
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.262
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-03: Version 7.8.261
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.260
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.259
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.258
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.257
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.256
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.255
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.254
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.253
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.252
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.251
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.250
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.249
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.248
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.247
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.246
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-02: Version 7.8.245
+
+ Performance and stability improvements on all platforms.
+
+
+2019-09-01: Version 7.8.244
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-31: Version 7.8.243
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-31: Version 7.8.242
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.241
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.240
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.239
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.238
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.237
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.236
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.235
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.234
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.233
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-30: Version 7.8.232
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.231
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.230
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.229
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.228
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.227
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.226
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.225
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.224
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.223
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.222
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-29: Version 7.8.221
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.220
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.219
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.218
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.217
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.216
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.215
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.214
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.213
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.212
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.211
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.210
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.209
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-28: Version 7.8.208
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.207
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.206
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.205
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.204
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.203
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.202
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-27: Version 7.8.201
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.200
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.199
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.198
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.197
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.196
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.195
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.194
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.193
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.192
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.191
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-26: Version 7.8.190
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-25: Version 7.8.189
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.188
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.187
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.186
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.185
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.184
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.183
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.182
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.181
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.180
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.179
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-23: Version 7.8.178
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.177
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.176
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.175
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.174
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.173
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.172
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.171
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.170
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.169
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.168
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.167
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.166
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.165
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.164
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.163
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.162
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.161
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.160
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.159
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.158
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-22: Version 7.8.157
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.156
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.155
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.154
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.153
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.152
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.151
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.150
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.149
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.148
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.147
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.146
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.145
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.144
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.143
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.142
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.141
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.140
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-21: Version 7.8.139
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.138
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.137
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.136
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.135
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.134
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.133
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.132
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.131
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.130
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.129
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.128
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.127
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.126
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.125
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.124
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.123
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.122
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.121
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-20: Version 7.8.120
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.119
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.118
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.117
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.116
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.115
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-19: Version 7.8.114
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-16: Version 7.8.113
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-15: Version 7.8.112
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.111
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.110
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.109
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.108
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.107
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-14: Version 7.8.106
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.105
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.104
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.103
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.102
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.101
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.100
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.99
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.98
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.97
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.96
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.95
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.94
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-13: Version 7.8.93
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.92
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.91
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.90
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.89
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.88
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.87
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.86
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.85
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.84
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.83
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.82
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.81
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.80
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.79
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-12: Version 7.8.78
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.77
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.76
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.75
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.74
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.73
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-09: Version 7.8.72
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-08: Version 7.8.71
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-08: Version 7.8.70
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-08: Version 7.8.69
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-08: Version 7.8.68
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-07: Version 7.8.67
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-07: Version 7.8.66
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-07: Version 7.8.65
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-06: Version 7.8.64
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-06: Version 7.8.63
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-06: Version 7.8.62
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-05: Version 7.8.61
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-05: Version 7.8.60
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-04: Version 7.8.59
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.58
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.57
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.56
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.55
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.54
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-02: Version 7.8.53
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.52
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.51
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.50
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.49
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.48
+
+ Performance and stability improvements on all platforms.
+
+
+2019-08-01: Version 7.8.47
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.46
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.45
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.44
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.43
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.42
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.41
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.40
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.39
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.38
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-31: Version 7.8.37
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.36
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.35
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.34
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.33
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.32
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.31
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.30
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.29
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.28
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.27
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.26
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.25
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.24
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.23
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.22
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.21
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.20
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.19
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.18
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.17
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-30: Version 7.8.16
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.15
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.14
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.13
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.12
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.11
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.10
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.9
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.8
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.7
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.6
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.5
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.4
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.3
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-29: Version 7.8.2
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-28: Version 7.8.1
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.310
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.309
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.308
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.307
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.306
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.305
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.304
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.303
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.302
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.301
+
+ Performance and stability improvements on all platforms.
+
+
+2019-07-24: Version 7.7.300
+
+ Performance and stability improvements on all platforms.
+
+
2019-07-23: Version 7.7.299
Performance and stability improvements on all platforms.
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index 986264356f99cc..a7d4081edb856c 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -3,6 +3,21 @@
# all paths in here must match this assumption.
vars = {
+ # Fetches only the SDK boot images which match at least one of the whitelist
+ # entries in a comma-separated list.
+ #
+ # Only the X64 and ARM64 QEMU images are downloaded by default. Developers
+ # that need to boot on other target architectures or devices can opt to
+ # download more boot images. Example of images include:
+ #
+ # Emulation:
+ # qemu.x64, qemu.arm64
+ # Hardware:
+ # generic.x64, generic.arm64
+ #
+ # Wildcards are supported (e.g. "qemu.*").
+ 'checkout_fuchsia_boot_images': "qemu.x64,qemu.arm64",
+
'checkout_instrumented_libraries': False,
'chromium_url': 'https://chromium.googlesource.com',
'android_url': 'https://android.googlesource.com',
@@ -12,7 +27,7 @@ vars = {
'check_v8_header_includes': False,
# GN CIPD package version.
- 'gn_version': 'git_revision:972ed755f8e6d31cae9ba15fcd08136ae1a7886f',
+ 'gn_version': 'git_revision:152c5144ceed9592c20f0c8fd55769646077569b',
# luci-go CIPD package version.
'luci_go': 'git_revision:7d11fd9e66407c49cb6c8546a2ae45ea993a240c',
@@ -20,7 +35,7 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
# and whatever else without interference from each other.
- 'android_sdk_build-tools_version': 'DLK621q5_Bga5EsOr7cp6bHWWxFKx6UHLu_Ix_m3AckC',
+ 'android_sdk_build-tools_version': '5DL7LQQjVMLClXLzLgmGysccPGsGcjJdvH9z5-uetiIC',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_emulator_version
# and whatever else without interference from each other.
@@ -57,15 +72,15 @@ vars = {
deps = {
'v8/build':
- Var('chromium_url') + '/chromium/src/build.git' + '@' + '1e5d7d692f816af8136c738b79fe9e8dde8057f6',
+ Var('chromium_url') + '/chromium/src/build.git' + '@' + '693faeda4ee025796c7e473d953a5a7b6ad64c93',
'v8/third_party/depot_tools':
- Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'ee7b9dda90e409fb92031d511151debe5db7db9f',
+ Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'f38bc1796282c61087dcf15abc61b8fd18a68402',
'v8/third_party/icu':
- Var('chromium_url') + '/chromium/deps/icu.git' + '@' + 'fd97d4326fac6da84452b2d5fe75ff0949368dab',
+ Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '53f6b233a41ec982d8445996247093f7aaf41639',
'v8/third_party/instrumented_libraries':
Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'b1c3ca20848c117eb935b02c25d441f03e6fbc5e',
'v8/buildtools':
- Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '67b293ca1316d06f7f00160ce35c92b8849a9dc9',
+ Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '74cfb57006f83cfe050817526db359d5c8a11628',
'v8/buildtools/clang_format/script':
Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917',
'v8/buildtools/linux64': {
@@ -105,9 +120,9 @@ deps = {
'condition': 'host_os == "win"',
},
'v8/base/trace_event/common':
- Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + 'cfe8887fa6ac3170e23a68949930e28d4705a16f',
+ Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + '5e4fce17a9d2439c44a7b57ceecef6df9287ec2f',
'v8/third_party/android_ndk': {
- 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '4e2cea441bfd43f0863d14f57b1e1844260b9884',
+ 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '62582753e869484bf0cc7f7e8d184ce0077033c2',
'condition': 'checkout_android',
},
'v8/third_party/android_sdk/public': {
@@ -153,7 +168,7 @@ deps = {
'dep_type': 'cipd',
},
'v8/third_party/catapult': {
- 'url': Var('chromium_url') + '/catapult.git' + '@' + '53913cecb11a3ef993f6496b9110964e2e2aeec3',
+ 'url': Var('chromium_url') + '/catapult.git' + '@' + 'e7c719c3e85f76938bf4fef0ba37c27f89246f71',
'condition': 'checkout_android',
},
'v8/third_party/colorama/src': {
@@ -161,11 +176,11 @@ deps = {
'condition': 'checkout_android',
},
'v8/third_party/fuchsia-sdk': {
- 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '5fd29151cf35c0813c33cc368a7c78389e3f5caa',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-sdk.git' + '@' + '1785f0ac8e1fe81cb25e260acbe7de8f62fa3e44',
'condition': 'checkout_fuchsia',
},
'v8/third_party/googletest/src':
- Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '6077f444da944d96d311d358d761164261f1cdd0',
+ Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '565f1b848215b77c3732bca345fe76a0431d8b34',
'v8/third_party/jinja2':
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'b41863e42637544c2941b574c7877d3e1f663e25',
'v8/third_party/markupsafe':
@@ -177,7 +192,7 @@ deps = {
'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' + '@' + '26a2268436f28f64c4539d9aab9ebd0f0b7c99c5',
+ Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '59a1a016b7cf5cf43f66b274c7d1db4ec6066935',
'v8/test/test262/harness':
Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b',
'v8/third_party/qemu-linux-x64': {
@@ -201,7 +216,7 @@ deps = {
'dep_type': 'cipd',
},
'v8/tools/clang':
- Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'f485a21a9cb05494161d97d545c3b29447610ffb',
+ Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '2fef805e5b05b26a8c87c47865590b5f43218611',
'v8/tools/luci-go': {
'packages': [
{
@@ -230,10 +245,8 @@ deps = {
'condition': 'checkout_mac',
'dep_type': 'cipd',
},
- 'v8/test/wasm-js/data':
- Var('chromium_url') + '/external/github.com/WebAssembly/spec.git' + '@' + '1a411f713d9850ce7da24719aba5bb80c535f562',
'v8/third_party/perfetto':
- Var('android_url') + '/platform/external/perfetto.git' + '@' + '0e8281399fd854de13461f2c1c9f2fb0b8e9c3ae',
+ Var('android_url') + '/platform/external/perfetto.git' + '@' + '01615892494a9a8dc84414962d0a817bf97de2c2',
'v8/third_party/protobuf':
Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91',
}
@@ -346,6 +359,17 @@ hooks = [
'-s', 'v8/test/wasm-spec-tests/tests.tar.gz.sha1',
],
},
+ {
+ 'name': 'wasm_js',
+ 'pattern': '.',
+ 'action': [ 'download_from_google_storage',
+ '--no_resume',
+ '--no_auth',
+ '-u',
+ '--bucket', 'v8-wasm-spec-tests',
+ '-s', 'v8/test/wasm-js/tests.tar.gz.sha1',
+ ],
+ },
{
'name': 'sysroot_arm',
'pattern': '.',
@@ -410,6 +434,13 @@ hooks = [
'condition': 'checkout_win',
'action': ['python', 'v8/build/vs_toolchain.py', 'update'],
},
+ {
+ # Update the Mac toolchain if necessary.
+ 'name': 'mac_toolchain',
+ 'pattern': '.',
+ 'condition': 'checkout_mac',
+ 'action': ['python', 'v8/build/mac_toolchain.py'],
+ },
# Pull binutils for linux, enabled debug fission for faster linking /
# debugging when used with clang on Ubuntu Precise.
# https://code.google.com/p/chromium/issues/detail?id=352046
@@ -444,6 +475,7 @@ hooks = [
'action': [
'python',
'v8/build/fuchsia/update_sdk.py',
+ '--boot-images={checkout_fuchsia_boot_images}',
],
},
{
diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS
index be360966665b38..9ab84b1e2759de 100644
--- a/deps/v8/OWNERS
+++ b/deps/v8/OWNERS
@@ -1,31 +1,31 @@
# Eng reviewer. Please reach out before adding new top-level directories.
# Disagreement among owners should be escalated to eng reviewers.
-file://ENG_REVIEW_OWNERS
+file:ENG_REVIEW_OWNERS
-per-file .clang-format=file://INFRA_OWNERS
-per-file .clang-tidy=file://INFRA_OWNERS
-per-file .editorconfig=file://INFRA_OWNERS
-per-file .flake8=file://INFRA_OWNERS
-per-file .git-blame-ignore-revs=file://INFRA_OWNERS
-per-file .gitattributes=file://INFRA_OWNERS
-per-file .gitignore=file://INFRA_OWNERS
-per-file .gn=file://INFRA_OWNERS
-per-file .vpython=file://INFRA_OWNERS
-per-file .ycm_extra_conf.py=file://INFRA_OWNERS
-per-file BUILD.gn=file://COMMON_OWNERS
-per-file DEPS=file://INFRA_OWNERS
+per-file .clang-format=file:INFRA_OWNERS
+per-file .clang-tidy=file:INFRA_OWNERS
+per-file .editorconfig=file:INFRA_OWNERS
+per-file .flake8=file:INFRA_OWNERS
+per-file .git-blame-ignore-revs=file:INFRA_OWNERS
+per-file .gitattributes=file:INFRA_OWNERS
+per-file .gitignore=file:INFRA_OWNERS
+per-file .gn=file:INFRA_OWNERS
+per-file .vpython=file:INFRA_OWNERS
+per-file .ycm_extra_conf.py=file:INFRA_OWNERS
+per-file BUILD.gn=file:COMMON_OWNERS
+per-file DEPS=file:INFRA_OWNERS
# For Test262 rolls.
per-file DEPS=mathias@chromium.org
-per-file PRESUBMIT=file://INFRA_OWNERS
-per-file codereview.settings=file://INFRA_OWNERS
+per-file PRESUBMIT=file:INFRA_OWNERS
+per-file codereview.settings=file:INFRA_OWNERS
-per-file AUTHORS=file://COMMON_OWNERS
-per-file WATCHLIST=file://COMMON_OWNERS
+per-file AUTHORS=file:COMMON_OWNERS
+per-file WATCHLIST=file:COMMON_OWNERS
-per-file *-mips*=file://MIPS_OWNERS
-per-file *-mips64*=file://MIPS_OWNERS
-per-file *-ppc*=file://PPC_OWNERS
-per-file *-s390*=file://S390_OWNERS
+per-file *-mips*=file:MIPS_OWNERS
+per-file *-mips64*=file:MIPS_OWNERS
+per-file *-ppc*=file:PPC_OWNERS
+per-file *-s390*=file:S390_OWNERS
# TEAM: v8-dev@googlegroups.com
# COMPONENT: Blink>JavaScript
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 f1878a18da91c6..57ac0254d96376 100644
--- a/deps/v8/base/trace_event/common/trace_event_common.h
+++ b/deps/v8/base/trace_event/common/trace_event_common.h
@@ -256,6 +256,13 @@
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val, \
arg2_name, arg2_val)
+#define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+ scope_and_flags)
+#define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+ scope_and_flags, arg1_name, arg1_val)
#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope, \
timestamp) \
@@ -285,12 +292,12 @@
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags)
+#define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
+ flags, arg1_name, arg1_val)
#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
@@ -341,12 +348,12 @@
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
arg2_name, arg2_val)
-#define TRACE_EVENT_COPY_END0(category_group, name) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_COPY)
-#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags)
+#define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name, \
+ arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \
+ arg1_name, arg1_val)
#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \
arg2_name, arg2_val) \
INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
@@ -580,6 +587,9 @@
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.
@@ -606,6 +616,11 @@
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
@@ -677,6 +692,9 @@
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, \
@@ -702,6 +720,11 @@
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
@@ -935,6 +958,9 @@
#define TRACE_TASK_EXECUTION(run_function, task) \
INTERNAL_TRACE_TASK_EXECUTION(run_function, task)
+#define TRACE_LOG_MESSAGE(file, message, line) \
+ INTERNAL_TRACE_LOG_MESSAGE(file, message, line)
+
// TRACE_EVENT_METADATA* events are information related to other
// injected events, not events in their own right.
#define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
@@ -1075,6 +1101,8 @@
// TODO(eseckler): Remove once we have native support for typed proto events in
// TRACE_EVENT macros.
#define TRACE_EVENT_FLAG_TYPED_PROTO_ARGS (static_cast(1 << 15))
+#define TRACE_EVENT_FLAG_JAVA_STRING_LITERALS \
+ (static_cast(1 << 16))
#define TRACE_EVENT_FLAG_SCOPE_MASK \
(static_cast(TRACE_EVENT_FLAG_SCOPE_OFFSET | \
diff --git a/deps/v8/benchmarks/OWNERS b/deps/v8/benchmarks/OWNERS
index 852d438bb0a884..3c70cea2fd5e6a 100644
--- a/deps/v8/benchmarks/OWNERS
+++ b/deps/v8/benchmarks/OWNERS
@@ -1 +1 @@
-file://COMMON_OWNERS
+file:../COMMON_OWNERS
diff --git a/deps/v8/build_overrides/OWNERS b/deps/v8/build_overrides/OWNERS
index bdb1d555a4fb98..cb04fa0838fbb5 100644
--- a/deps/v8/build_overrides/OWNERS
+++ b/deps/v8/build_overrides/OWNERS
@@ -1 +1 @@
-file://INFRA_OWNERS
+file:../INFRA_OWNERS
diff --git a/deps/v8/build_overrides/build.gni b/deps/v8/build_overrides/build.gni
index 12ef8b28d6b612..5b99eb94022596 100644
--- a/deps/v8/build_overrides/build.gni
+++ b/deps/v8/build_overrides/build.gni
@@ -35,5 +35,16 @@ tsan_suppressions_file = "//build/sanitizers/tsan_suppressions.cc"
# Skip assertions about 4GiB file size limit.
ignore_elf32_limitations = true
-# Use the system install of Xcode for tools like ibtool, libtool, etc.
-use_system_xcode = true
+if (host_os == "mac") {
+ _result = exec_script("//build/mac/should_use_hermetic_xcode.py",
+ [ target_os ],
+ "value")
+ assert(_result != 2,
+ "Do not allow building targets with the default" +
+ "hermetic toolchain if the minimum OS version is not met.")
+ assert(_result != 3,
+ "iOS does not support building with a hermetic toolchain. " +
+ "Please install Xcode.")
+
+ use_system_xcode = _result == 0
+}
diff --git a/deps/v8/custom_deps/OWNERS b/deps/v8/custom_deps/OWNERS
index bdb1d555a4fb98..cb04fa0838fbb5 100644
--- a/deps/v8/custom_deps/OWNERS
+++ b/deps/v8/custom_deps/OWNERS
@@ -1 +1 @@
-file://INFRA_OWNERS
+file:../INFRA_OWNERS
diff --git a/deps/v8/gni/OWNERS b/deps/v8/gni/OWNERS
index bdb1d555a4fb98..cb04fa0838fbb5 100644
--- a/deps/v8/gni/OWNERS
+++ b/deps/v8/gni/OWNERS
@@ -1 +1 @@
-file://INFRA_OWNERS
+file:../INFRA_OWNERS
diff --git a/deps/v8/gni/snapshot_toolchain.gni b/deps/v8/gni/snapshot_toolchain.gni
index f4f1f1d88e258d..b5fb1823b382e0 100644
--- a/deps/v8/gni/snapshot_toolchain.gni
+++ b/deps/v8/gni/snapshot_toolchain.gni
@@ -107,3 +107,12 @@ if (v8_snapshot_toolchain == "") {
assert(v8_snapshot_toolchain != "",
"Do not know how to build a snapshot for $current_toolchain " +
"on $host_os $host_cpu")
+
+# We reuse the snapshot toolchain for building torque and other generators to
+# avoid building v8_libbase on the host more than once. On mips with big endian,
+# the snapshot toolchain is the target toolchain and, hence, can't be used.
+v8_generator_toolchain = v8_snapshot_toolchain
+if (host_cpu == "x64" &&
+ (v8_current_cpu == "mips" || v8_current_cpu == "mips64")) {
+ v8_generator_toolchain = "//build/toolchain/linux:clang_x64"
+}
diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS
index 7ffbf74ce94d90..b64069847bc1cc 100644
--- a/deps/v8/include/OWNERS
+++ b/deps/v8/include/OWNERS
@@ -3,8 +3,8 @@ danno@chromium.org
ulan@chromium.org
yangguo@chromium.org
-per-file *DEPS=file://COMMON_OWNERS
-per-file v8-internal.h=file://COMMON_OWNERS
+per-file *DEPS=file:../COMMON_OWNERS
+per-file v8-internal.h=file:../COMMON_OWNERS
per-file v8-inspector.h=dgozman@chromium.org
per-file v8-inspector.h=pfeldman@chromium.org
per-file v8-inspector.h=kozyatinskiy@chromium.org
diff --git a/deps/v8/include/libplatform/v8-tracing.h b/deps/v8/include/libplatform/v8-tracing.h
index e7cd8bfcdb66d0..df145e95bf723b 100644
--- a/deps/v8/include/libplatform/v8-tracing.h
+++ b/deps/v8/include/libplatform/v8-tracing.h
@@ -244,6 +244,8 @@ class V8_PLATFORM_EXPORT TracingController
TracingController();
~TracingController() override;
+
+ // Takes ownership of |trace_buffer|.
void Initialize(TraceBuffer* trace_buffer);
#ifdef V8_USE_PERFETTO
// Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides
diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h
index fe2ce67e0df04e..8ce88fb3efcba8 100644
--- a/deps/v8/include/v8-internal.h
+++ b/deps/v8/include/v8-internal.h
@@ -63,8 +63,8 @@ struct SmiTagging<4> {
V8_INLINE static int SmiToInt(const internal::Address value) {
int shift_bits = kSmiTagSize + kSmiShiftSize;
- // Shift down (requires >> to be sign extending).
- return static_cast(static_cast(value)) >> shift_bits;
+ // Truncate and shift down (requires >> to be sign extending).
+ return static_cast(static_cast(value)) >> shift_bits;
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
// Is value in range [kSmiMinValue, kSmiMaxValue].
diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h
index 645920d9c1b357..2c7d4b12e29123 100644
--- a/deps/v8/include/v8-profiler.h
+++ b/deps/v8/include/v8-profiler.h
@@ -26,6 +26,10 @@ struct CpuProfileDeoptFrame {
size_t position;
};
+namespace internal {
+class CpuProfile;
+} // namespace internal
+
} // namespace v8
#ifdef V8_OS_WIN
@@ -48,75 +52,6 @@ template class V8_EXPORT std::vector;
namespace v8 {
-// TickSample captures the information collected for each sample.
-struct V8_EXPORT TickSample {
- // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
- // include the runtime function we're calling. Externally exposed tick
- // samples don't care.
- enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
-
- TickSample()
- : state(OTHER),
- pc(nullptr),
- external_callback_entry(nullptr),
- frames_count(0),
- has_external_callback(false),
- update_stats(true) {}
-
- /**
- * Initialize a tick sample from the isolate.
- * \param isolate The isolate.
- * \param state Execution state.
- * \param record_c_entry_frame Include or skip the runtime function.
- * \param update_stats Whether update the sample to the aggregated stats.
- * \param use_simulator_reg_state When set to true and V8 is running under a
- * simulator, the method will use the simulator
- * register state rather than the one provided
- * with |state| argument. Otherwise the method
- * will use provided register |state| as is.
- */
- void Init(Isolate* isolate, const v8::RegisterState& state,
- RecordCEntryFrame record_c_entry_frame, bool update_stats,
- bool use_simulator_reg_state = true);
- /**
- * Get a call stack sample from the isolate.
- * \param isolate The isolate.
- * \param state Register state.
- * \param record_c_entry_frame Include or skip the runtime function.
- * \param frames Caller allocated buffer to store stack frames.
- * \param frames_limit Maximum number of frames to capture. The buffer must
- * be large enough to hold the number of frames.
- * \param sample_info The sample info is filled up by the function
- * provides number of actual captured stack frames and
- * the current VM state.
- * \param use_simulator_reg_state When set to true and V8 is running under a
- * simulator, the method will use the simulator
- * register state rather than the one provided
- * with |state| argument. Otherwise the method
- * will use provided register |state| as is.
- * \note GetStackSample is thread and signal safe and should only be called
- * when the JS thread is paused or interrupted.
- * Otherwise the behavior is undefined.
- */
- static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
- RecordCEntryFrame record_c_entry_frame,
- void** frames, size_t frames_limit,
- v8::SampleInfo* sample_info,
- bool use_simulator_reg_state = true);
- StateTag state; // The state of the VM.
- void* pc; // Instruction pointer.
- union {
- void* tos; // Top stack value (*sp).
- void* external_callback_entry;
- };
- static const unsigned kMaxFramesCountLog2 = 8;
- static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
- void* stack[kMaxFramesCount]; // Call stack.
- unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
- bool has_external_callback : 1;
- bool update_stats : 1; // Whether the sample should update aggregated stats.
-};
-
/**
* CpuProfileNode represents a node in a call graph.
*/
@@ -307,6 +242,15 @@ enum CpuProfilingNamingMode {
kDebugNaming,
};
+enum CpuProfilingLoggingMode {
+ // Enables logging when a profile is active, and disables logging when all
+ // profiles are detached.
+ kLazyLogging,
+ // Enables logging for the lifetime of the CpuProfiler. Calls to
+ // StartRecording are faster, at the expense of runtime overhead.
+ kEagerLogging,
+};
+
/**
* Optional profiling attributes.
*/
@@ -340,6 +284,11 @@ class V8_EXPORT CpuProfilingOptions {
int sampling_interval_us() const { return sampling_interval_us_; }
private:
+ friend class internal::CpuProfile;
+
+ bool has_filter_context() const;
+ void* raw_filter_context() const;
+
CpuProfilingMode mode_;
unsigned max_samples_;
int sampling_interval_us_;
@@ -359,6 +308,9 @@ class V8_EXPORT CpuProfiler {
static CpuProfiler* New(Isolate* isolate);
static CpuProfiler* New(Isolate* isolate,
CpuProfilingNamingMode mode);
+ static CpuProfiler* New(Isolate* isolate,
+ CpuProfilingNamingMode namingMode,
+ CpuProfilingLoggingMode loggingMode);
/**
* Synchronously collect current stack sample in all profilers attached to
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index a87655058a058d..38881eb38fcbbf 100644
--- a/deps/v8/include/v8-version.h
+++ b/deps/v8/include/v8-version.h
@@ -9,9 +9,9 @@
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define V8_MAJOR_VERSION 7
-#define V8_MINOR_VERSION 7
-#define V8_BUILD_NUMBER 299
-#define V8_PATCH_LEVEL 13
+#define V8_MINOR_VERSION 8
+#define V8_BUILD_NUMBER 279
+#define V8_PATCH_LEVEL 23
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index f3fbdc696294e4..aa19cf8caadf79 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -19,6 +19,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -129,6 +131,7 @@ class PropertyCallbackArguments;
class FunctionCallbackArguments;
class GlobalHandles;
class ScopedExternalStringLock;
+class ThreadLocalTop;
namespace wasm {
class NativeModule;
@@ -823,24 +826,43 @@ template
using UniquePersistent = Global;
/**
- * A traced handle with move semantics, similar to std::unique_ptr. The handle
- * is to be used together with |v8::EmbedderHeapTracer| and specifies edges from
- * the embedder into V8's heap.
+ * Trait specifying behavior of |TracedGlobal|.
+ */
+template
+struct TracedGlobalTrait {
+ /**
+ * Specifies whether |TracedGlobal| should clear its handle on destruction.
+ *
+ * V8 will *not* clear the embedder-side memory of the handle. The embedder is
+ * expected to report all |TracedGlobal| handles through
+ * |EmbedderHeapTracer| upon garabge collection.
+ *
+ * See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with
+ * non-tracing GCs in V8.
+ */
+ static constexpr bool kRequiresExplicitDestruction = true;
+};
+
+/**
+ * A traced handle with copy and move semantics. The handle is to be used
+ * together with |v8::EmbedderHeapTracer| and specifies edges from the embedder
+ * into V8's heap.
*
* The exact semantics are:
* - Tracing garbage collections use |v8::EmbedderHeapTracer|.
* - Non-tracing garbage collections refer to
* |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should
* be treated as root or not.
+ *
+ * For destruction semantics see |TracedGlobalTrait|.
*/
template
-class V8_EXPORT TracedGlobal {
+class TracedGlobal {
public:
/**
* An empty TracedGlobal without storage cell.
*/
TracedGlobal() = default;
- ~TracedGlobal() { Reset(); }
/**
* Construct a TracedGlobal from a Local.
@@ -857,7 +879,41 @@ class V8_EXPORT TracedGlobal {
/**
* Move constructor initializing TracedGlobal from an existing one.
*/
- V8_INLINE TracedGlobal(TracedGlobal&& other);
+ V8_INLINE TracedGlobal(TracedGlobal&& other) {
+ // Forward to operator=.
+ *this = std::move(other);
+ }
+
+ /**
+ * Move constructor initializing TracedGlobal from an existing one.
+ */
+ template
+ V8_INLINE TracedGlobal(TracedGlobal&& other) {
+ // Forward to operator=.
+ *this = std::move(other);
+ }
+
+ /**
+ * Copy constructor initializing TracedGlobal from an existing one.
+ */
+ V8_INLINE TracedGlobal(const TracedGlobal& other) {
+ // Forward to operator=;
+ *this = other;
+ }
+
+ /**
+ * Copy constructor initializing TracedGlobal from an existing one.
+ */
+ template
+ V8_INLINE TracedGlobal(const TracedGlobal& other) {
+ // Forward to operator=;
+ *this = other;
+ }
+
+ /**
+ * Move assignment operator initializing TracedGlobal from an existing one.
+ */
+ V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs);
/**
* Move assignment operator initializing TracedGlobal from an existing one.
@@ -866,10 +922,21 @@ class V8_EXPORT TracedGlobal {
V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs);
/**
- * TracedGlobal only supports move semantics and forbids copying.
+ * Copy assignment operator initializing TracedGlobal from an existing one.
+ *
+ * Note: Prohibited when |other| has a finalization callback set through
+ * |SetFinalizationCallback|.
+ */
+ V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs);
+
+ /**
+ * Copy assignment operator initializing TracedGlobal from an existing one.
+ *
+ * Note: Prohibited when |other| has a finalization callback set through
+ * |SetFinalizationCallback|.
*/
- TracedGlobal(const TracedGlobal&) = delete;
- void operator=(const TracedGlobal&) = delete;
+ template
+ V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs);
/**
* Returns true if this TracedGlobal is empty, i.e., has not been assigned an
@@ -903,8 +970,8 @@ class V8_EXPORT TracedGlobal {
template
V8_INLINE bool operator==(const TracedGlobal& that) const {
- internal::Address* a = reinterpret_cast(this->val_);
- internal::Address* b = reinterpret_cast(that.val_);
+ internal::Address* a = reinterpret_cast(**this);
+ internal::Address* b = reinterpret_cast(*that);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
@@ -912,8 +979,8 @@ class V8_EXPORT TracedGlobal {
template
V8_INLINE bool operator==(const Local& that) const {
- internal::Address* a = reinterpret_cast(this->val_);
- internal::Address* b = reinterpret_cast(that.val_);
+ internal::Address* a = reinterpret_cast(**this);
+ internal::Address* b = reinterpret_cast(*that);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
@@ -954,11 +1021,32 @@ class V8_EXPORT TracedGlobal {
void* parameter, WeakCallbackInfo::Callback callback);
private:
- V8_INLINE static T* New(Isolate* isolate, T* that, T** slot);
+ // Wrapping type used when clearing on destruction is required.
+ struct WrappedForDestruction {
+ T* value;
+
+ explicit WrappedForDestruction(T* val) : value(val) {}
+ ~WrappedForDestruction();
+ operator T*() const { return value; }
+ T* operator*() const { return value; }
+ T* operator->() const { return value; }
+ WrappedForDestruction& operator=(const WrappedForDestruction& other) {
+ value = other.value;
+ return *this;
+ }
+ WrappedForDestruction& operator=(T* val) {
+ value = val;
+ return *this;
+ }
+ };
+
+ V8_INLINE static T* New(Isolate* isolate, T* that, void* slot);
T* operator*() const { return this->val_; }
- T* val_ = nullptr;
+ typename std::conditional<
+ TracedGlobalTrait>::kRequiresExplicitDestruction,
+ WrappedForDestruction, T*>::type val_{nullptr};
friend class EmbedderHeapTracer;
template
@@ -1385,11 +1473,19 @@ class V8_EXPORT Module {
/**
* Set this module's exported value for the name export_name to the specified
* export_value. This method must be called only on Modules created via
- * CreateSyntheticModule. export_name must be one of the export_names that
- * were passed in that CreateSyntheticModule call.
+ * CreateSyntheticModule. An error will be thrown if export_name is not one
+ * of the export_names that were passed in that CreateSyntheticModule call.
+ * Returns Just(true) on success, Nothing() if an error was thrown.
*/
- void SetSyntheticModuleExport(Local export_name,
- Local export_value);
+ V8_WARN_UNUSED_RESULT Maybe SetSyntheticModuleExport(
+ Isolate* isolate, Local export_name, Local export_value);
+ V8_DEPRECATE_SOON(
+ "Use the preceding SetSyntheticModuleExport with an Isolate parameter, "
+ "instead of the one that follows. The former will throw a runtime "
+ "error if called for an export that doesn't exist (as per spec); "
+ "the latter will crash with a failed CHECK().",
+ void SetSyntheticModuleExport(Local export_name,
+ Local export_value));
};
/**
@@ -3782,6 +3878,15 @@ class V8_EXPORT Object : public Value {
*/
bool IsConstructor();
+ /**
+ * True if this object can carry information relevant to the embedder in its
+ * embedder fields, false otherwise. This is generally true for objects
+ * constructed through function templates but also holds for other types where
+ * V8 automatically adds internal fields at compile time, such as e.g.
+ * v8::ArrayBuffer.
+ */
+ bool IsApiWrapper();
+
/**
* Call an Object as a function if a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
@@ -4850,8 +4955,8 @@ class V8_EXPORT ArrayBuffer : public Object {
bool IsDetachable() const;
// TODO(913887): fix the use of 'neuter' in the API.
- V8_DEPRECATE_SOON("Use IsDetachable() instead.",
- inline bool IsNeuterable() const) {
+ V8_DEPRECATED("Use IsDetachable() instead.",
+ inline bool IsNeuterable() const) {
return IsDetachable();
}
@@ -4864,7 +4969,7 @@ class V8_EXPORT ArrayBuffer : public Object {
void Detach();
// TODO(913887): fix the use of 'neuter' in the API.
- V8_DEPRECATE_SOON("Use Detach() instead.", inline void Neuter()) { Detach(); }
+ V8_DEPRECATED("Use Detach() instead.", inline void Neuter()) { Detach(); }
/**
* Make this ArrayBuffer external. The pointer to underlying memory block
@@ -5502,6 +5607,32 @@ class V8_EXPORT RegExp : public Object {
static void CheckCast(Value* obj);
};
+/**
+ * An instance of the built-in FinalizationGroup constructor.
+ *
+ * This API is experimental and may change significantly.
+ */
+class V8_EXPORT FinalizationGroup : public Object {
+ public:
+ /**
+ * Runs the cleanup callback of the given FinalizationGroup.
+ *
+ * V8 will inform the embedder that there are finalizer callbacks be
+ * called through HostCleanupFinalizationGroupCallback.
+ *
+ * HostCleanupFinalizationGroupCallback should schedule a task to
+ * call FinalizationGroup::Cleanup() at some point in the
+ * future. It's the embedders responsiblity to make this call at a
+ * time which does not interrupt synchronous ECMAScript code
+ * execution.
+ *
+ * If the result is Nothing then an exception has
+ * occurred. Otherwise the result is |true| if the cleanup callback
+ * was called successfully. The result is never |false|.
+ */
+ static V8_WARN_UNUSED_RESULT Maybe Cleanup(
+ Local finalization_group);
+};
/**
* A JavaScript value that wraps a C++ void*. This type of value is mainly used
@@ -6743,10 +6874,34 @@ typedef void* (*CreateHistogramCallback)(const char* name,
typedef void (*AddHistogramSampleCallback)(void* histogram, int sample);
+// --- Crashkeys Callback ---
+enum class CrashKeyId {
+ kIsolateAddress,
+ kReadonlySpaceFirstPageAddress,
+ kMapSpaceFirstPageAddress,
+ kCodeSpaceFirstPageAddress,
+};
+
+typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value);
+
// --- Enter/Leave Script Callback ---
typedef void (*BeforeCallEnteredCallback)(Isolate*);
typedef void (*CallCompletedCallback)(Isolate*);
+/**
+ * HostCleanupFinalizationGroupCallback is called when we require the
+ * embedder to enqueue a task that would call
+ * FinalizationGroup::Cleanup().
+ *
+ * The FinalizationGroup is the one for which the embedder needs to
+ * call FinalizationGroup::Cleanup() on.
+ *
+ * The context provided is the one in which the FinalizationGroup was
+ * created in.
+ */
+typedef void (*HostCleanupFinalizationGroupCallback)(
+ Local context, Local fg);
+
/**
* HostImportModuleDynamicallyCallback is called when we require the
* embedder to load a module. This is used as part of the dynamic
@@ -7006,6 +7161,10 @@ typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo&);
// --- Callback for checking if WebAssembly threads are enabled ---
typedef bool (*WasmThreadsEnabledCallback)(Local context);
+// --- Callback for loading source map file for WASM profiling support
+typedef Local (*WasmLoadSourceMapCallback)(Isolate* isolate,
+ const char* name);
+
// --- Garbage Collection Callbacks ---
/**
@@ -7382,7 +7541,7 @@ class V8_EXPORT EmbedderHeapTracer {
/**
* Called at the beginning of a GC cycle.
*/
- V8_DEPRECATE_SOON("Use version with flags.", virtual void TracePrologue()) {}
+ V8_DEPRECATED("Use version with flags.", virtual void TracePrologue()) {}
virtual void TracePrologue(TraceFlags flags);
/**
@@ -7433,14 +7592,37 @@ class V8_EXPORT EmbedderHeapTracer {
/**
* Returns true if the TracedGlobal handle should be considered as root for
* the currently running non-tracing garbage collection and false otherwise.
+ * The default implementation will keep all TracedGlobal references as roots.
*
- * Default implementation will keep all TracedGlobal references as roots.
+ * If this returns false, then V8 may decide that the object referred to by
+ * such a handle is reclaimed. In that case:
+ * - No action is required if handles are used with destructors.
+ * - When run without destructors (by specializing
+ * |TracedGlobalTrait::kRequiresExplicitDestruction|) V8 calls
+ * |ResetHandleInNonTracingGC|.
+ *
+ * Note that the |handle| is different from the |TracedGlobal| handle that
+ * the embedder holds for retaining the object. The embedder may use
+ * |TracedGlobal::WrapperClassId()| to distinguish cases where it wants
+ * handles to be treated as roots from not being treated as roots.
*/
virtual bool IsRootForNonTracingGC(
const v8::TracedGlobal& handle) {
return true;
}
+ /**
+ * Used in combination with |IsRootForNonTracingGC|. Called by V8 when an
+ * object that is backed by a handle is reclaimed by a non-tracing garbage
+ * collection. It is up to the embedder to reset the original handle.
+ *
+ * Note that the |handle| is different from the |TracedGlobal| handle that
+ * the embedder holds for retaining the object. It is up to the embedder to
+ * find the orignal |TracedGlobal| handle via the object or class id.
+ */
+ virtual void ResetHandleInNonTracingGC(
+ const v8::TracedGlobal& handle) {}
+
/*
* Called by the embedder to immediately perform a full garbage collection.
*
@@ -7660,7 +7842,6 @@ class V8_EXPORT Isolate {
class V8_EXPORT SuppressMicrotaskExecutionScope {
public:
explicit SuppressMicrotaskExecutionScope(Isolate* isolate);
- explicit SuppressMicrotaskExecutionScope(MicrotaskQueue* microtask_queue);
~SuppressMicrotaskExecutionScope();
// Prevent copying of Scope objects.
@@ -7671,7 +7852,15 @@ class V8_EXPORT Isolate {
private:
internal::Isolate* const isolate_;
- internal::MicrotaskQueue* const microtask_queue_;
+ internal::Address previous_stack_height_;
+ static_assert(sizeof(internal::Address) ==
+ sizeof(internal::MicrotaskQueue*) &&
+ alignof(internal::Address) ==
+ alignof(internal::MicrotaskQueue*),
+ "The previous_stack_height_ field can replace the "
+ "microtask_queue_ field ABI-wise");
+
+ friend class internal::ThreadLocalTop;
};
/**
@@ -7785,9 +7974,10 @@ class V8_EXPORT Isolate {
kStringNormalize = 75,
kCallSiteAPIGetFunctionSloppyCall = 76,
kCallSiteAPIGetThisSloppyCall = 77,
+ kRegExpMatchAllWithNonGlobalRegExp = 78,
// If you add new values here, you'll also need to update Chromium's:
- // web_feature.mojom, UseCounterCallback.cpp, and enums.xml. V8 changes to
+ // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to
// this list need to be landed first, then changes on the Chromium side.
kUseCounterFeatureCount // This enum value must be last.
};
@@ -7845,6 +8035,18 @@ class V8_EXPORT Isolate {
*/
static Isolate* GetCurrent();
+ /**
+ * Clears the set of objects held strongly by the heap. This set of
+ * objects are originally built when a WeakRef is created or
+ * successfully dereferenced.
+ *
+ * The embedder is expected to call this when a synchronous sequence
+ * of ECMAScript execution completes. It's the embedders
+ * responsiblity to make this call at a time which does not
+ * interrupt synchronous ECMAScript code execution.
+ */
+ void ClearKeptObjects();
+
/**
* Custom callback used by embedders to help V8 determine if it should abort
* when it throws and no internal handler is predicted to catch the
@@ -7858,6 +8060,14 @@ class V8_EXPORT Isolate {
void SetAbortOnUncaughtExceptionCallback(
AbortOnUncaughtExceptionCallback callback);
+ /**
+ * This specifies the callback to be called when finalization groups
+ * are ready to be cleaned up and require FinalizationGroup::Cleanup()
+ * to be called in a future task.
+ */
+ void SetHostCleanupFinalizationGroupCallback(
+ HostCleanupFinalizationGroupCallback callback);
+
/**
* This specifies the callback called by the upcoming dynamic
* import() language feature to load modules.
@@ -8411,6 +8621,13 @@ class V8_EXPORT Isolate {
void SetCreateHistogramFunction(CreateHistogramCallback);
void SetAddHistogramSampleFunction(AddHistogramSampleCallback);
+ /**
+ * Enables the host application to provide a mechanism for recording a
+ * predefined set of data as crash keys to be used in postmortem debugging in
+ * case of a crash.
+ */
+ void SetAddCrashKeyCallback(AddCrashKeyCallback);
+
/**
* Optional notification that the embedder is idle.
* V8 uses the notification to perform garbage collection.
@@ -8610,6 +8827,8 @@ class V8_EXPORT Isolate {
void SetWasmThreadsEnabledCallback(WasmThreadsEnabledCallback callback);
+ void SetWasmLoadSourceMapCallback(WasmLoadSourceMapCallback callback);
+
/**
* Check if V8 is dead and therefore unusable. This is the case after
* fatal errors such as out-of-memory situations.
@@ -8970,11 +9189,14 @@ class V8_EXPORT V8 {
internal::Address* handle);
static internal::Address* GlobalizeTracedReference(internal::Isolate* isolate,
internal::Address* handle,
- internal::Address* slot);
+ internal::Address* slot,
+ bool has_destructor);
static void MoveGlobalReference(internal::Address** from,
internal::Address** to);
static void MoveTracedGlobalReference(internal::Address** from,
internal::Address** to);
+ static void CopyTracedGlobalReference(const internal::Address* const* from,
+ internal::Address** to);
static internal::Address* CopyGlobalReference(internal::Address* from);
static void DisposeGlobal(internal::Address* global_handle);
static void DisposeTracedGlobal(internal::Address* global_handle);
@@ -10093,18 +10315,26 @@ Global& Global::operator=(Global&& rhs) {
}
template
-T* TracedGlobal::New(Isolate* isolate, T* that, T** slot) {
+TracedGlobal::WrappedForDestruction::~WrappedForDestruction() {
+ if (value == nullptr) return;
+ V8::DisposeTracedGlobal(reinterpret_cast(value));
+ value = nullptr;
+}
+
+template
+T* TracedGlobal::New(Isolate* isolate, T* that, void* slot) {
if (that == nullptr) return nullptr;
internal::Address* p = reinterpret_cast(that);
return reinterpret_cast(V8::GlobalizeTracedReference(
reinterpret_cast(isolate), p,
- reinterpret_cast(slot)));
+ reinterpret_cast(slot),
+ TracedGlobalTrait>::kRequiresExplicitDestruction));
}
template
void TracedGlobal::Reset() {
if (IsEmpty()) return;
- V8::DisposeTracedGlobal(reinterpret_cast(val_));
+ V8::DisposeTracedGlobal(reinterpret_cast(**this));
val_ = nullptr;
}
@@ -10118,19 +10348,23 @@ void TracedGlobal::Reset(Isolate* isolate, const Local& other) {
}
template
-TracedGlobal::TracedGlobal(TracedGlobal&& other) : val_(other.val_) {
- if (other.val_ != nullptr) {
- V8::MoveTracedGlobalReference(
- reinterpret_cast(&other.val_),
- reinterpret_cast(&this->val_));
- other.val_ = nullptr;
- }
+template
+TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) {
+ TYPE_CHECK(T, S);
+ *this = std::move(rhs.template As());
+ return *this;
}
template
template
-TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) {
+TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) {
TYPE_CHECK(T, S);
+ *this = rhs.template As();
+ return *this;
+}
+
+template
+TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) {
if (this != &rhs) {
this->Reset();
if (rhs.val_ != nullptr) {
@@ -10144,11 +10378,24 @@ TracedGlobal& TracedGlobal::operator=(TracedGlobal&& rhs) {
return *this;
}
+template
+TracedGlobal& TracedGlobal::operator=(const TracedGlobal& rhs) {
+ if (this != &rhs) {
+ this->Reset();
+ if (rhs.val_ != nullptr) {
+ V8::CopyTracedGlobalReference(
+ reinterpret_cast(&rhs.val_),
+ reinterpret_cast(&this->val_));
+ }
+ }
+ return *this;
+}
+
template
void TracedGlobal::SetWrapperClassId(uint16_t class_id) {
typedef internal::Internals I;
if (IsEmpty()) return;
- internal::Address* obj = reinterpret_cast(this->val_);
+ internal::Address* obj = reinterpret_cast(**this);
uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset;
*reinterpret_cast(addr) = class_id;
}
@@ -10157,7 +10404,7 @@ template
uint16_t TracedGlobal::WrapperClassId() const {
typedef internal::Internals I;
if (IsEmpty()) return 0;
- internal::Address* obj = reinterpret_cast(this->val_);
+ internal::Address* obj = reinterpret_cast(**this);
uint8_t* addr = reinterpret_cast(obj) + I::kNodeClassIdOffset;
return *reinterpret_cast(addr);
}
@@ -10166,7 +10413,7 @@ template
void TracedGlobal::SetFinalizationCallback(
void* parameter, typename WeakCallbackInfo::Callback callback) {
V8::SetFinalizationCallbackTraced(
- reinterpret_cast(this->val_), parameter, callback);
+ reinterpret_cast(**this), parameter, callback);
}
template
@@ -11111,9 +11358,12 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
}
if (change_in_bytes < 0) {
- const int64_t lower_limit = *external_memory_limit + change_in_bytes;
- if (lower_limit > I::kExternalAllocationSoftLimit)
+ const int64_t lower_limit =
+ static_cast(static_cast(*external_memory_limit) +
+ static_cast(change_in_bytes));
+ if (lower_limit > I::kExternalAllocationSoftLimit) {
*external_memory_limit = lower_limit;
+ }
} else if (change_in_bytes > 0 && amount > *external_memory_limit) {
ReportExternalAllocationLimitReached();
}
diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h
index 7bd2938225bc74..7670c0e449c7fd 100644
--- a/deps/v8/include/v8config.h
+++ b/deps/v8/include/v8config.h
@@ -186,6 +186,8 @@
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported
// V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported
+// V8_HAS_COMPUTED_GOTO - computed goto/labels as values
+// supported
// V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported
// V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
@@ -214,6 +216,7 @@
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result))
+# define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned))
# define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16))
# define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32))
# define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64))
@@ -226,6 +229,10 @@
# define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow))
# define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow))
+// Clang has no __has_feature for computed gotos.
+// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+# define V8_HAS_COMPUTED_GOTO 1
+
# if __cplusplus >= 201402L
# define V8_CAN_HAVE_DCHECK_IN_CONSTEXPR 1
# endif
@@ -256,12 +263,16 @@
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
+# define V8_HAS_BUILTIN_ASSUME_ALIGNED (V8_GNUC_PREREQ(4, 7, 0))
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0))
# define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0))
# define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0))
+// GCC doc: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+#define V8_HAS_COMPUTED_GOTO (V8_GNUC_PREREQ(2, 0, 0))
+
#endif
#if defined(_MSC_VER)
@@ -291,6 +302,12 @@
# define V8_INLINE inline
#endif
+#if V8_HAS_BUILTIN_ASSUME_ALIGNED
+# define V8_ASSUME_ALIGNED(ptr, alignment) \
+ __builtin_assume_aligned((ptr), (alignment))
+#else
+# define V8_ASSUME_ALIGNED(ptr) (ptr)
+#endif
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
diff --git a/deps/v8/infra/OWNERS b/deps/v8/infra/OWNERS
index a75a43666efa57..a33a8ba8ed96fa 100644
--- a/deps/v8/infra/OWNERS
+++ b/deps/v8/infra/OWNERS
@@ -1,3 +1,3 @@
-file://INFRA_OWNERS
+file:../INFRA_OWNERS
tandrii@chromium.org
diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl
index 965300da7735f2..305007354d7509 100644
--- a/deps/v8/infra/testing/builders.pyl
+++ b/deps/v8/infra/testing/builders.pyl
@@ -485,13 +485,8 @@
'swarming_dimensions' : {
'os': 'Ubuntu-16.04',
},
- 'swarming_task_attrs': {
- 'expiration': 14400,
- 'hard_timeout': 3600,
- 'priority': 35,
- },
'tests': [
- {'name': 'v8testing', 'shards': 7},
+ {'name': 'v8testing', 'shards': 12},
],
},
##############################################################################
@@ -548,7 +543,7 @@
# Win64
'v8_win64_asan_rel_ng_triggered': {
'swarming_dimensions' : {
- 'os': 'Windows-10',
+ 'os': 'Windows-10-15063',
},
'tests': [
{'name': 'v8testing', 'shards': 5},
@@ -834,7 +829,7 @@
},
'tests': [
{'name': 'mozilla', 'variant': 'default'},
- {'name': 'test262', 'variant': 'default', 'shards': 4},
+ {'name': 'test262', 'variant': 'default', 'shards': 6},
{'name': 'v8testing', 'variant': 'default', 'shards': 3},
],
},
@@ -1260,7 +1255,7 @@
},
'V8 Win64 ASAN': {
'swarming_dimensions': {
- 'os': 'Windows-10',
+ 'os': 'Windows-10-15063',
},
'tests': [
{'name': 'v8testing', 'shards': 5},
@@ -1412,8 +1407,8 @@
'os': 'Ubuntu-16.04',
},
'tests': [
- {'name': 'mjsunit_sp_frame_access'},
- {'name': 'mozilla'},
+ {'name': 'mjsunit_sp_frame_access', 'shards': 4},
+ {'name': 'mozilla', 'shards': 4},
{'name': 'test262', 'variant': 'default'},
{'name': 'v8testing', 'shards': 8},
{'name': 'v8testing', 'variant': 'extra', 'shards': 4},
@@ -1423,14 +1418,14 @@
'name': 'mozilla',
'suffix': 'armv8-a',
'test_args': ['--extra-flags', '--enable-armv8'],
- 'shards': 2,
+ 'shards': 3,
},
{
'name': 'test262',
'suffix': 'armv8-a',
'variant': 'default',
'test_args': ['--extra-flags', '--enable-armv8'],
- 'shards': 2,
+ 'shards': 3,
},
{
'name': 'v8testing',
@@ -1822,9 +1817,9 @@
'os': 'Ubuntu-16.04',
},
'tests': [
- {'name': 'mozilla'},
- {'name': 'test262', 'variant': 'default'},
- {'name': 'v8testing', 'shards': 8},
+ {'name': 'mozilla', 'shards': 2},
+ {'name': 'test262', 'variant': 'default', 'shards': 2},
+ {'name': 'v8testing', 'shards': 10},
],
},
'V8 arm - sim - stable branch': {
@@ -1842,9 +1837,9 @@
'os': 'Ubuntu-16.04',
},
'tests': [
- {'name': 'mozilla'},
- {'name': 'test262', 'variant': 'default'},
- {'name': 'v8testing', 'shards': 8},
+ {'name': 'mozilla', 'shards': 2},
+ {'name': 'test262', 'variant': 'default', 'shards': 2},
+ {'name': 'v8testing', 'shards': 10},
],
},
'V8 mips64el - sim - beta branch': {
diff --git a/deps/v8/src/OWNERS b/deps/v8/src/OWNERS
index c6881f232117b2..3e21b6ea369970 100644
--- a/deps/v8/src/OWNERS
+++ b/deps/v8/src/OWNERS
@@ -1,5 +1,5 @@
-per-file *DEPS=file://COMMON_OWNERS
-per-file intl-*=file://INTL_OWNERS
-per-file *-intl*=file://INTL_OWNERS
+per-file *DEPS=file:../COMMON_OWNERS
+per-file intl-*=file:../INTL_OWNERS
+per-file *-intl*=file:../INTL_OWNERS
# COMPONENT: Blink>JavaScript
diff --git a/deps/v8/src/api/OWNERS b/deps/v8/src/api/OWNERS
index ce6fb20af84d38..ef5a56dbfcecf3 100644
--- a/deps/v8/src/api/OWNERS
+++ b/deps/v8/src/api/OWNERS
@@ -1,4 +1,4 @@
-file://include/OWNERS
+file:../../include/OWNERS
clemensh@chromium.org
ishell@chromium.org
jkummerow@chromium.org
diff --git a/deps/v8/src/api/api-inl.h b/deps/v8/src/api/api-inl.h
index d152412b474f95..1a6b512e83a651 100644
--- a/deps/v8/src/api/api-inl.h
+++ b/deps/v8/src/api/api-inl.h
@@ -8,6 +8,7 @@
#include "src/api/api.h"
#include "src/handles/handles-inl.h"
#include "src/objects/foreign-inl.h"
+#include "src/objects/js-weak-refs.h"
#include "src/objects/objects-inl.h"
#include "src/objects/stack-frame-info.h"
@@ -84,6 +85,7 @@ MAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
MAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
MAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
MAKE_TO_LOCAL(ToLocalShared, JSArrayBuffer, SharedArrayBuffer)
+MAKE_TO_LOCAL(ToLocal, JSFinalizationGroup, FinalizationGroup)
TYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY)
diff --git a/deps/v8/src/api/api-natives.cc b/deps/v8/src/api/api-natives.cc
index cd380d3cda1aa2..b96b6fc4f62b2e 100644
--- a/deps/v8/src/api/api-natives.cc
+++ b/deps/v8/src/api/api-natives.cc
@@ -42,9 +42,17 @@ MaybeHandle InstantiateObject(Isolate* isolate,
bool is_prototype);
MaybeHandle InstantiateFunction(
- Isolate* isolate, Handle data,
+ Isolate* isolate, Handle native_context,
+ Handle data,
MaybeHandle maybe_name = MaybeHandle());
+MaybeHandle InstantiateFunction(
+ Isolate* isolate, Handle data,
+ MaybeHandle maybe_name = MaybeHandle()) {
+ return InstantiateFunction(isolate, isolate->native_context(), data,
+ maybe_name);
+}
+
MaybeHandle