Skip to content

Commit

Permalink
vm: add Script.createCodeCache()
Browse files Browse the repository at this point in the history
PR-URL: #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>
  • Loading branch information
devsnek committed Jun 26, 2018
1 parent a9d9d76 commit 4f67c6f
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 2 deletions.
9 changes: 9 additions & 0 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions doc/api/vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
26 changes: 24 additions & 2 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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(
Expand All @@ -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);

Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-vm-createcacheddata.js
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 4f67c6f

Please sign in to comment.