vm: add Script.createCodeCache()
PR-URL: https://github.com/nodejs/node/pull/20300 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Yang Guo <yangguo@chromium.org>
This commit is contained in:
parent
a9d9d7689d
commit
4f67c6f667
@ -1005,6 +1005,14 @@ accepted by the legacy `url.parse()` API. The mentioned APIs now use the WHATWG
|
||||
URL parser that requires strictly valid URLs. Passing an invalid URL is
|
||||
deprecated and support will be removed in the future.
|
||||
|
||||
<a id="DEP00XX"></a>
|
||||
### DEP00XX: vm.Script cached data
|
||||
|
||||
Type: Documentation-only
|
||||
|
||||
The option `produceCachedData` has been deprecated. Use
|
||||
[`script.createCachedData()`][] instead.
|
||||
|
||||
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
|
||||
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
|
||||
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
|
||||
@ -1055,6 +1063,7 @@ deprecated and support will be removed in the future.
|
||||
[`process.env`]: process.html#process_process_env
|
||||
[`punycode`]: punycode.html
|
||||
[`require.extensions`]: modules.html#modules_require_extensions
|
||||
[`script.createCachedData()`]: vm.html#vm_script_create_cached_data
|
||||
[`setInterval()`]: timers.html#timers_setinterval_callback_delay_args
|
||||
[`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args
|
||||
[`tls.CryptoStream`]: tls.html#tls_class_cryptostream
|
||||
|
@ -411,6 +411,10 @@ changes:
|
||||
pr-url: https://github.com/nodejs/node/pull/4777
|
||||
description: The `cachedData` and `produceCachedData` options are
|
||||
supported now.
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/20300
|
||||
description: The `produceCachedData` is deprecated in favour of
|
||||
`script.createCachedData()`
|
||||
-->
|
||||
|
||||
* `code` {string} The JavaScript code to compile.
|
||||
@ -431,11 +435,39 @@ changes:
|
||||
`cachedData` property of the returned `vm.Script` instance.
|
||||
The `cachedDataProduced` value will be set to either `true` or `false`
|
||||
depending on whether code cache data is produced successfully.
|
||||
This option is deprecated in favor of `script.createCachedData`.
|
||||
|
||||
Creating a new `vm.Script` object compiles `code` but does not run it. The
|
||||
compiled `vm.Script` can be run later multiple times. The `code` is not bound to
|
||||
any global object; rather, it is bound before each run, just for that run.
|
||||
|
||||
### script.createCachedData()
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* Returns: {Buffer}
|
||||
|
||||
Creates a code cache that can be used with the Script constructor's
|
||||
`cachedData` option. Returns a Buffer. This method may be called at any
|
||||
time and any number of times.
|
||||
|
||||
```js
|
||||
const script = new vm.Script(`
|
||||
function add(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
const x = add(1, 2);
|
||||
`);
|
||||
|
||||
const cacheWithoutX = script.createCachedData();
|
||||
|
||||
script.runInThisContext();
|
||||
|
||||
const cacheWithX = script.createCachedData();
|
||||
```
|
||||
|
||||
### script.runInContext(contextifiedSandbox[, options])
|
||||
<!-- YAML
|
||||
added: v0.3.1
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "base_object-inl.h"
|
||||
#include "node_contextify.h"
|
||||
#include "node_context_data.h"
|
||||
#include "node_errors.h"
|
||||
|
||||
namespace node {
|
||||
namespace contextify {
|
||||
@ -596,6 +597,7 @@ class ContextifyScript : public BaseObject {
|
||||
Local<FunctionTemplate> script_tmpl = env->NewFunctionTemplate(New);
|
||||
script_tmpl->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
script_tmpl->SetClassName(class_name);
|
||||
env->SetProtoMethod(script_tmpl, "createCachedData", CreateCachedData);
|
||||
env->SetProtoMethod(script_tmpl, "runInContext", RunInContext);
|
||||
env->SetProtoMethod(script_tmpl, "runInThisContext", RunInThisContext);
|
||||
|
||||
@ -637,7 +639,7 @@ class ContextifyScript : public BaseObject {
|
||||
Local<Context> parsing_context = context;
|
||||
|
||||
if (argc > 2) {
|
||||
// new ContextifyScript(code, filename, lineOffset, columnOffset
|
||||
// new ContextifyScript(code, filename, lineOffset, columnOffset,
|
||||
// cachedData, produceCachedData, parsingContext)
|
||||
CHECK_EQ(argc, 7);
|
||||
CHECK(args[2]->IsNumber());
|
||||
@ -719,7 +721,7 @@ class ContextifyScript : public BaseObject {
|
||||
Boolean::New(isolate, source.GetCachedData()->rejected));
|
||||
} else if (produce_cached_data) {
|
||||
const ScriptCompiler::CachedData* cached_data =
|
||||
ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked(), code);
|
||||
ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked());
|
||||
bool cached_data_produced = cached_data != nullptr;
|
||||
if (cached_data_produced) {
|
||||
MaybeLocal<Object> buf = Buffer::Copy(
|
||||
@ -745,6 +747,26 @@ class ContextifyScript : public BaseObject {
|
||||
}
|
||||
|
||||
|
||||
static void CreateCachedData(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
ContextifyScript* wrapped_script;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder());
|
||||
Local<UnboundScript> unbound_script =
|
||||
PersistentToLocal(env->isolate(), wrapped_script->script_);
|
||||
std::unique_ptr<ScriptCompiler::CachedData> cached_data(
|
||||
ScriptCompiler::CreateCodeCache(unbound_script));
|
||||
if (!cached_data) {
|
||||
args.GetReturnValue().Set(Buffer::New(env, 0).ToLocalChecked());
|
||||
} else {
|
||||
MaybeLocal<Object> buf = Buffer::Copy(
|
||||
env,
|
||||
reinterpret_cast<const char*>(cached_data->data),
|
||||
cached_data->length);
|
||||
args.GetReturnValue().Set(buf.ToLocalChecked());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void RunInThisContext(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
|
22
test/parallel/test-vm-createcacheddata.js
Normal file
22
test/parallel/test-vm-createcacheddata.js
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
|
||||
const { Script } = require('vm');
|
||||
const assert = require('assert');
|
||||
|
||||
const source = 'function x() {} const y = x();';
|
||||
|
||||
const script = new Script(source);
|
||||
let cachedData = script.createCachedData();
|
||||
assert(cachedData instanceof Buffer);
|
||||
|
||||
assert(!new Script(source, { cachedData }).cachedDataRejected);
|
||||
|
||||
script.runInNewContext();
|
||||
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
cachedData = script.createCachedData();
|
||||
|
||||
assert(!new Script(source, { cachedData }).cachedDataRejected);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user