-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vm: add bindings for v8::CompileFunctionInContext #21571
Conversation
src/node_contextify.cc
Outdated
std::vector<Local<String>> params; | ||
if (!params_buf.IsEmpty()) { | ||
for (uint32_t n = 0; n < params_buf->Length(); n++) { | ||
Local<Value> val = params_buf->Get(context, n).ToLocalChecked(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you return if Get()
returns an empty MaybeLocal
?
src/node_contextify.cc
Outdated
} | ||
fun->Set( | ||
env->cached_data_produced_string(), | ||
Boolean::New(isolate, cached_data_produced)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use the non-deprecated overloads of Set()
?
|
||
// Argument 4: column offset | ||
CHECK(args[3]->IsNumber()); | ||
Local<Integer> column_offset = args[3].As<Integer>(); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
env->cached_data_string(), | ||
buf.ToLocalChecked()).IsNothing()) return; | ||
} | ||
if (fun->Set( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if the return value was something like { function, codeCache }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could be rad, but I'm supposing that most people would just be expecting the function or would disable the cache and then we'll be returning { function }
, which doesn't look super good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like mentioned previously, let's not have this at all, and expose ScriptCompiler::CreateCodeCacheForFunction
in a separate binding like we already do for ScriptCompiler::CreateCodeCache
.
|
||
// Argument 3: line offset | ||
CHECK(args[2]->IsNumber()); | ||
Local<Integer> line_offset = args[2].As<Integer>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have it been tested these offsets actually do anything for compiling functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea, my guess is that we set them to 0 for like... 99% cases, but I put them in just for parity with ContextifyScript::New
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well in ContextifyScript the entire source can be offset for dealing with source positions in html bodies and such. if they don't do anything here it would be best to remove them. (easy test is offset by a bunch and make the body have a syntax error, then read the column offset in the stack)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you ever verify this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be useful.
One way to test this is to throw an exception ans check whether the exception position is affected by the offsets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It indeed works. Will add tests.
@addaleax added typechecking for |
@ryzokuken If you have a |
Should we discuss the option of splitting code caching into a separate function entirely? There is no reason to bundle it with compilation aside from symmetry with ContextifyScript::New, where the code caching option is going to be deprecated. |
Cool, will add the checks in JS-Land for all options as well, in that case. |
Definitely. I think that's what we're going towards for |
@hashseed what happens if the target of CreateCodeCacheForFunction wasn't created by CompileFunction? is there a way to tell the difference between invalid target and other reasons cache would fail? |
lib/vm.js
Outdated
@@ -286,6 +287,36 @@ function runInThisContext(code, options) { | |||
return createScript(code, options).runInThisContext(options); | |||
} | |||
|
|||
function compileFunction(code, params, options) { | |||
const defaults = { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seemed a better option, true, but now I'm also using defaults
for error checking, so I guess it's good enough?
lib/vm.js
Outdated
if (typeof code !== 'string') { | ||
throw new ERR_INVALID_ARG_TYPE('code', 'string', code); | ||
} | ||
if (Array.isArray(params)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can save a level of indentation here if you check for !Array.isArray(params)
with a throw
, and drop the else
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -128,3 +128,30 @@ const vm = require('vm'); | |||
'Received type object' | |||
}); | |||
}); | |||
|
|||
// vm.compileFunction |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
All: Please take a final look at this, will be landing this tomorrow morning. |
src/node_contextify.cc
Outdated
|
||
if (produce_cached_data) { | ||
const ScriptCompiler::CachedData* cached_data = | ||
ScriptCompiler::CreateCodeCacheForFunction(fun, code); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the late review...
lib/vm.js
Outdated
filename, | ||
columnOffset, | ||
lineOffset, | ||
cachedData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not type-checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate? It is checked if cachedData
is an Object
or not, but it's not checked in it's a Uint8Array
. Do you propose I add checking for the exact type? I think I should do that, but couldn't find instances of the same in the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you propose I add checking for the exact type?
Yes.
I think I should do that, but couldn't find instances of the same in the codebase.
Because the entire (or at least most of) codebase is now free of Uint8Array-only functions. You could use isUint8Array()
in internal/util/types.js
for this purpose.
lib/vm.js
Outdated
@@ -286,6 +287,72 @@ function runInThisContext(code, options) { | |||
return createScript(code, options).runInThisContext(options); | |||
} | |||
|
|||
function compileFunction(code, params, options) { | |||
const defaults = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This object should be lifted out of the function as it's never changed. Optionally it can also be Object.freeze()
d.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, defaults
object won't be necessary if you instead use destructuring with defaults as I did in #21571 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's exactly what @targos suggested, but then I'm also using the same object for type-checking. Would transition to a hard-coded types approach instead of the inferred approach as used here, it sounds better in this case anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would transition to a hard-coded types approach instead of the inferred approach as used here
Yes that is exactly what I'm suggesting in #21571 (comment).
// Argument 5: cached data (optional) | ||
Local<Uint8Array> cached_data_buf; | ||
if (!args[4]->IsUndefined()) { | ||
CHECK(args[4]->IsUint8Array()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should accept all ArrayBuffer view types, and ArrayBuffer itself, consistent with other newer APIs. Hint: use Buffer::HasInstance()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d stick with consistency with Script::New
, and maybe relax this in a later PR for both of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds great to me. @TimothyGu wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); | ||
uint8_t* data = static_cast<uint8_t*>(contents.Data()); | ||
cached_data = new ScriptCompiler::CachedData( | ||
data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Buffer
methods should simplify this quite a bit, as they take care of byte offsets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hasn't been fixed yet. Note, you don't need to support all types of ArrayBufferView
to use Buffer
methods. In fact you can do a direct switch of data + cached_data_buf->ByteOffset()
by Buffer::Data(cached_data_buf)
and cached_data_buf->ByteLength()
by Buffer::Length(cached_data_buf)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that, and had been planning to change these in both CompileFunction
and Script::New
in a quick subsequent PR. I could make one right now, if you'd like.
Or would you still prefer that I make the switch in this one and just change Script::New
in the other PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, do as you planned :)
lib/vm.js
Outdated
} | ||
|
||
if (options !== undefined) { | ||
for (const key in options) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not using for
-in
loops for checking types... it doesn't scale well when we want to add new options with odd types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any suggestions on what I should use instead? I think I should with Object.keys(options).forEach(...)
, but I not a lot of alternatives come to mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do
const {
optionA = 'default value',
optionB,
optionC
} = options;
if (typeof optionA !== 'string') {
throw ...
}
if (optionB !== undefined && !isContext(optionB)) {
throw ...
}
validateInteger(optionC);
|
||
// Argument 3: line offset | ||
CHECK(args[2]->IsNumber()); | ||
Local<Integer> line_offset = args[2].As<Integer>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Number type is indeed checked in JavaScript, but not that the number is an integer. That should be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will throw in Number.isInteger
checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW you should use validateInteger()
in internal/validators.js
.
Testing the new changes locally, let's merge it in the next few days and proceed? TODOs for subsequent PRs:
|
lib/vm.js
Outdated
} | ||
if (parsingContext !== undefined) { | ||
try { | ||
isContext(parsingContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isContext
returns a boolean for objects. You probably want something like if (typeof parsingContext !== 'object' || parsingContext === null || !isContext(parsingContext))
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried exactly that, but apparently isContext
throws by itself?
function isContext(sandbox) {
if (typeof sandbox !== 'object' || sandbox === null) {
throw new ERR_INVALID_ARG_TYPE('sandbox', 'Object', sandbox);
}
return _isContext(sandbox);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it throws for non-objects, but returns a boolean for objects. Check out the implementation for _isContext
:
Lines 261 to 271 in 978d89f
void ContextifyContext::IsContext(const FunctionCallbackInfo<Value>& args) { | |
Environment* env = Environment::GetCurrent(args); | |
CHECK(args[0]->IsObject()); | |
Local<Object> sandbox = args[0].As<Object>(); | |
Maybe<bool> result = | |
sandbox->HasPrivate(env->context(), | |
env->contextify_context_private_symbol()); | |
args.GetReturnValue().Set(result.FromJust()); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the thing: it throws for null as well as non-objects, and I'm testing for null, which complicates things. Isn't null
an object too? It shouldn't fail the CHECK
, right?
ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); | ||
uint8_t* data = static_cast<uint8_t*>(contents.Data()); | ||
cached_data = new ScriptCompiler::CachedData( | ||
data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hasn't been fixed yet. Note, you don't need to support all types of ArrayBufferView
to use Buffer
methods. In fact you can do a direct switch of data + cached_data_buf->ByteOffset()
by Buffer::Data(cached_data_buf)
and cached_data_buf->ByteLength()
by Buffer::Length(cached_data_buf)
.
@TimothyGu PTAL |
lib/vm.js
Outdated
parsingContext | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👆 All that validation stuff is super clean. I dig it 👍
} | ||
}); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👆 I know many internals try to avoid prototypal methods directly (opting to create generic forms). Should this be done for forEach
use?
Update:
Same with isArray
(e.g. const { isArray } = Array
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've generally tried to avoid using forEach
within core functions because it's an order of magnitude slower than a regular for-loop. Even if this is not expected to be a hot function, I think I'd rather see this as a regular for-loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we're taking the performance approach, forEach
has actually become faster in the common case than a for loop (in V8 anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👆 \cc @bmeurer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever the outcome of this discussion, please let’s not hold up the PR over this – this isn’t hot code (or at least the cost of actual parsing + compilation is likely going to overshadow any choice of this kind), so I think it’s fine to go with whatever the PR author considers most readable.
Optimistic CI Run: https://ci.nodejs.org/job/node-test-pull-request/15811/ (last couple of runs failed) |
Code LGTM. This just needs to be documented. |
Re-run custom-suites CI: https://ci.nodejs.org/job/node-test-commit-custom-suites/627/ |
@ryzokuken ... can I ask you to squash the fixup commits down? This doesn't land cleanly with all of the edits. |
@jasnell totally! I had been waiting for everyone to approve this before squashing. Gimme a minute. |
9f8bad6
to
a5f85ad
Compare
@jasnell done! PTAL. |
New CI after rebase: https://ci.nodejs.org/job/node-test-pull-request/16389/ |
This needs another quick rebase then I can run CI again. |
@jasnell on it! |
Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap
a5f85ad
to
bbd542e
Compare
@jasnell That should do it. Thanks! |
Landed in 1abbe0a 🎉 |
Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap PR-URL: nodejs#21571 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap PR-URL: #21571 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap PR-URL: #21571 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Notable changes: * child_process: * `TypedArray` and `DataView` values are now accepted as input by `execFileSync` and `spawnSync`. #22409 * coverage: * Native V8 code coverage information can now be output to disk by setting the environment variable `NODE_V8_COVERAGE` to a directory. #22527 * deps: * The bundled npm was upgraded to version 6.4.1. #22591 * Changelogs: [6.3.0-next.0](https://github.com/npm/cli/releases/tag/v6.3.0-next.0) [6.3.0](https://github.com/npm/cli/releases/tag/v6.3.0) [6.4.0](https://github.com/npm/cli/releases/tag/v6.4.0) [6.4.1](https://github.com/npm/cli/releases/tag/v6.4.1) * fs: * The methods `fs.read`, `fs.readSync`, `fs.write`, `fs.writeSync`, `fs.writeFile` and `fs.writeFileSync` now all accept `TypedArray` and `DataView` objects. #22150 * A new boolean option, `withFileTypes`, can be passed to to `fs.readdir` and `fs.readdirSync`. If set to true, the methods return an array of directory entries. These are objects that can be used to determine the type of each entry and filter them based on that without calling `fs.stat`. #22020 * http2: * The `http2` module is no longer experimental. #22466 * os: * Added two new methods: `os.getPriority` and `os.setPriority`, allowing to manipulate the scheduling priority of processes. #22394 * process: * Added `process.allowedNodeEnvironmentFlags`. This object can be used to programmatically validate and list flags that are allowed in the `NODE_OPTIONS` environment variable. #19335 * src: * Deprecated option variables in public C++ API. #22392 * Refactored options parsing. #22392 * vm: * Added `vm.compileFunction`, a method to create new JavaScript functions from a source body, with options similar to those of the other `vm` methods. #21571 * Added new collaborators: * [lundibundi](https://github.com/lundibundi) - Denys Otrishko PR-URL: #22716
Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap PR-URL: #21571 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Notable changes: * child_process: * `TypedArray` and `DataView` values are now accepted as input by `execFileSync` and `spawnSync`. #22409 * coverage: * Native V8 code coverage information can now be output to disk by setting the environment variable `NODE_V8_COVERAGE` to a directory. #22527 * deps: * The bundled npm was upgraded to version 6.4.1. #22591 * Changelogs: [6.3.0-next.0](https://github.com/npm/cli/releases/tag/v6.3.0-next.0) [6.3.0](https://github.com/npm/cli/releases/tag/v6.3.0) [6.4.0](https://github.com/npm/cli/releases/tag/v6.4.0) [6.4.1](https://github.com/npm/cli/releases/tag/v6.4.1) * fs: * The methods `fs.read`, `fs.readSync`, `fs.write`, `fs.writeSync`, `fs.writeFile` and `fs.writeFileSync` now all accept `TypedArray` and `DataView` objects. #22150 * A new boolean option, `withFileTypes`, can be passed to to `fs.readdir` and `fs.readdirSync`. If set to true, the methods return an array of directory entries. These are objects that can be used to determine the type of each entry and filter them based on that without calling `fs.stat`. #22020 * http2: * The `http2` module is no longer experimental. #22466 * os: * Added two new methods: `os.getPriority` and `os.setPriority`, allowing to manipulate the scheduling priority of processes. #22407 * process: * Added `process.allowedNodeEnvironmentFlags`. This object can be used to programmatically validate and list flags that are allowed in the `NODE_OPTIONS` environment variable. #19335 * src: * Deprecated option variables in public C++ API. #22515 * Refactored options parsing. #22392 * vm: * Added `vm.compileFunction`, a method to create new JavaScript functions from a source body, with options similar to those of the other `vm` methods. #21571 * Added new collaborators: * [lundibundi](https://github.com/lundibundi) - Denys Otrishko PR-URL: #22716
Notable changes: * child_process: * `TypedArray` and `DataView` values are now accepted as input by `execFileSync` and `spawnSync`. #22409 * coverage: * Native V8 code coverage information can now be output to disk by setting the environment variable `NODE_V8_COVERAGE` to a directory. #22527 * deps: * The bundled npm was upgraded to version 6.4.1. #22591 * Changelogs: [6.3.0-next.0](https://github.com/npm/cli/releases/tag/v6.3.0-next.0) [6.3.0](https://github.com/npm/cli/releases/tag/v6.3.0) [6.4.0](https://github.com/npm/cli/releases/tag/v6.4.0) [6.4.1](https://github.com/npm/cli/releases/tag/v6.4.1) * fs: * The methods `fs.read`, `fs.readSync`, `fs.write`, `fs.writeSync`, `fs.writeFile` and `fs.writeFileSync` now all accept `TypedArray` and `DataView` objects. #22150 * A new boolean option, `withFileTypes`, can be passed to to `fs.readdir` and `fs.readdirSync`. If set to true, the methods return an array of directory entries. These are objects that can be used to determine the type of each entry and filter them based on that without calling `fs.stat`. #22020 * http2: * The `http2` module is no longer experimental. #22466 * os: * Added two new methods: `os.getPriority` and `os.setPriority`, allowing to manipulate the scheduling priority of processes. #22407 * process: * Added `process.allowedNodeEnvironmentFlags`. This object can be used to programmatically validate and list flags that are allowed in the `NODE_OPTIONS` environment variable. #19335 * src: * Deprecated option variables in public C++ API. #22515 * Refactored options parsing. #22392 * vm: * Added `vm.compileFunction`, a method to create new JavaScript functions from a source body, with options similar to those of the other `vm` methods. #21571 * Added new collaborators: * [lundibundi](https://github.com/lundibundi) - Denys Otrishko PR-URL: #22716
Notable changes: * child_process: * `TypedArray` and `DataView` values are now accepted as input by `execFileSync` and `spawnSync`. #22409 * coverage: * Native V8 code coverage information can now be output to disk by setting the environment variable `NODE_V8_COVERAGE` to a directory. #22527 * deps: * The bundled npm was upgraded to version 6.4.1. #22591 * Changelogs: [6.3.0-next.0](https://github.com/npm/cli/releases/tag/v6.3.0-next.0) [6.3.0](https://github.com/npm/cli/releases/tag/v6.3.0) [6.4.0](https://github.com/npm/cli/releases/tag/v6.4.0) [6.4.1](https://github.com/npm/cli/releases/tag/v6.4.1) * fs: * The methods `fs.read`, `fs.readSync`, `fs.write`, `fs.writeSync`, `fs.writeFile` and `fs.writeFileSync` now all accept `TypedArray` and `DataView` objects. #22150 * A new boolean option, `withFileTypes`, can be passed to to `fs.readdir` and `fs.readdirSync`. If set to true, the methods return an array of directory entries. These are objects that can be used to determine the type of each entry and filter them based on that without calling `fs.stat`. #22020 * http2: * The `http2` module is no longer experimental. #22466 * os: * Added two new methods: `os.getPriority` and `os.setPriority`, allowing to manipulate the scheduling priority of processes. #22407 * process: * Added `process.allowedNodeEnvironmentFlags`. This object can be used to programmatically validate and list flags that are allowed in the `NODE_OPTIONS` environment variable. #19335 * src: * Deprecated option variables in public C++ API. #22515 * Refactored options parsing. #22392 * vm: * Added `vm.compileFunction`, a method to create new JavaScript functions from a source body, with options similar to those of the other `vm` methods. #21571 * Added new collaborators: * [lundibundi](https://github.com/lundibundi) - Denys Otrishko PR-URL: #22716
Adds a method compileFunction to the vm module, which serves as a
binding for v8::CompileFunctionInContext with appropriate args for
specifying the details, and provide params for the wrapper.
Eventually, we would be changing Module._compile to use this internally
over the standard Module.wrap
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesTODO
/cc @nodejs/vm @nodejs/v8 @hashseed