Skip to content

Commit 4fc05ac

Browse files
devsnektargos
authored andcommitted
vm: add Script.createCodeCache()
PR-URL: #20300 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: John-David Dalton <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Yang Guo <[email protected]>
1 parent 9f2bf3c commit 4fc05ac

File tree

4 files changed

+87
-2
lines changed

4 files changed

+87
-2
lines changed

doc/api/deprecations.md

+9
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,14 @@ because it also made sense to interpret the value as the number of bytes
993993
read by the engine, but is inconsistent with other streams in Node.js that
994994
expose values under these names.
995995
996+
<a id="DEP00XX"></a>
997+
### DEP00XX: vm.Script cached data
998+
999+
Type: Documentation-only
1000+
1001+
The option `produceCachedData` has been deprecated. Use
1002+
[`script.createCachedData()`][] instead.
1003+
9961004
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
9971005
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
9981006
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
@@ -1039,6 +1047,7 @@ expose values under these names.
10391047
[`process.env`]: process.html#process_process_env
10401048
[`punycode`]: punycode.html
10411049
[`require.extensions`]: modules.html#modules_require_extensions
1050+
[`script.createCachedData()`]: vm.html#vm_script_create_cached_data
10421051
[`setInterval()`]: timers.html#timers_setinterval_callback_delay_args
10431052
[`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args
10441053
[`tls.CryptoStream`]: tls.html#tls_class_cryptostream

doc/api/vm.md

+32
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ changes:
411411
pr-url: https://github.com/nodejs/node/pull/4777
412412
description: The `cachedData` and `produceCachedData` options are
413413
supported now.
414+
- version: REPLACEME
415+
pr-url: https://github.com/nodejs/node/pull/20300
416+
description: The `produceCachedData` is deprecated in favour of
417+
`script.createCachedData()`
414418
-->
415419

416420
* `code` {string} The JavaScript code to compile.
@@ -431,11 +435,39 @@ changes:
431435
`cachedData` property of the returned `vm.Script` instance.
432436
The `cachedDataProduced` value will be set to either `true` or `false`
433437
depending on whether code cache data is produced successfully.
438+
This option is deprecated in favor of `script.createCachedData`.
434439

435440
Creating a new `vm.Script` object compiles `code` but does not run it. The
436441
compiled `vm.Script` can be run later multiple times. The `code` is not bound to
437442
any global object; rather, it is bound before each run, just for that run.
438443

444+
### script.createCachedData()
445+
<!-- YAML
446+
added: REPLACEME
447+
-->
448+
449+
* Returns: {Buffer}
450+
451+
Creates a code cache that can be used with the Script constructor's
452+
`cachedData` option. Returns a Buffer. This method may be called at any
453+
time and any number of times.
454+
455+
```js
456+
const script = new vm.Script(`
457+
function add(a, b) {
458+
return a + b;
459+
}
460+
461+
const x = add(1, 2);
462+
`);
463+
464+
const cacheWithoutX = script.createCachedData();
465+
466+
script.runInThisContext();
467+
468+
const cacheWithX = script.createCachedData();
469+
```
470+
439471
### script.runInContext(contextifiedSandbox[, options])
440472
<!-- YAML
441473
added: v0.3.1

src/node_contextify.cc

+24-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "base_object-inl.h"
2525
#include "node_contextify.h"
2626
#include "node_context_data.h"
27+
#include "node_errors.h"
2728

2829
namespace node {
2930
namespace contextify {
@@ -595,6 +596,7 @@ class ContextifyScript : public BaseObject {
595596
Local<FunctionTemplate> script_tmpl = env->NewFunctionTemplate(New);
596597
script_tmpl->InstanceTemplate()->SetInternalFieldCount(1);
597598
script_tmpl->SetClassName(class_name);
599+
env->SetProtoMethod(script_tmpl, "createCachedData", CreateCachedData);
598600
env->SetProtoMethod(script_tmpl, "runInContext", RunInContext);
599601
env->SetProtoMethod(script_tmpl, "runInThisContext", RunInThisContext);
600602

@@ -636,7 +638,7 @@ class ContextifyScript : public BaseObject {
636638
Local<Context> parsing_context = context;
637639

638640
if (argc > 2) {
639-
// new ContextifyScript(code, filename, lineOffset, columnOffset
641+
// new ContextifyScript(code, filename, lineOffset, columnOffset,
640642
// cachedData, produceCachedData, parsingContext)
641643
CHECK_EQ(argc, 7);
642644
CHECK(args[2]->IsNumber());
@@ -718,7 +720,7 @@ class ContextifyScript : public BaseObject {
718720
Boolean::New(isolate, source.GetCachedData()->rejected));
719721
} else if (produce_cached_data) {
720722
const ScriptCompiler::CachedData* cached_data =
721-
ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked(), code);
723+
ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked());
722724
bool cached_data_produced = cached_data != nullptr;
723725
if (cached_data_produced) {
724726
MaybeLocal<Object> buf = Buffer::Copy(
@@ -744,6 +746,26 @@ class ContextifyScript : public BaseObject {
744746
}
745747

746748

749+
static void CreateCachedData(const FunctionCallbackInfo<Value>& args) {
750+
Environment* env = Environment::GetCurrent(args);
751+
ContextifyScript* wrapped_script;
752+
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder());
753+
Local<UnboundScript> unbound_script =
754+
PersistentToLocal(env->isolate(), wrapped_script->script_);
755+
std::unique_ptr<ScriptCompiler::CachedData> cached_data(
756+
ScriptCompiler::CreateCodeCache(unbound_script));
757+
if (!cached_data) {
758+
args.GetReturnValue().Set(Buffer::New(env, 0).ToLocalChecked());
759+
} else {
760+
MaybeLocal<Object> buf = Buffer::Copy(
761+
env,
762+
reinterpret_cast<const char*>(cached_data->data),
763+
cached_data->length);
764+
args.GetReturnValue().Set(buf.ToLocalChecked());
765+
}
766+
}
767+
768+
747769
static void RunInThisContext(const FunctionCallbackInfo<Value>& args) {
748770
Environment* env = Environment::GetCurrent(args);
749771

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
const { Script } = require('vm');
6+
const assert = require('assert');
7+
8+
const source = 'function x() {} const y = x();';
9+
10+
const script = new Script(source);
11+
let cachedData = script.createCachedData();
12+
assert(cachedData instanceof Buffer);
13+
14+
assert(!new Script(source, { cachedData }).cachedDataRejected);
15+
16+
script.runInNewContext();
17+
18+
for (let i = 0; i < 10; i += 1) {
19+
cachedData = script.createCachedData();
20+
21+
assert(!new Script(source, { cachedData }).cachedDataRejected);
22+
}

0 commit comments

Comments
 (0)