Skip to content

Commit d5c04c3

Browse files
jray319indutny
authored andcommitted
vm: fix produceCachedData
Fix segmentation faults when compiling the same code with `produceCachedData` option. V8 ignores the option when the code is in its compilation cache and does not return cached data. Added `cachedDataProduced` property to `v8.Script` to denote whether the cached data is produced successfully. PR-URL: nodejs#5343 Reviewed-By: Fedor Indutny <fedor@indutny.com>
1 parent 5c14efb commit d5c04c3

4 files changed

Lines changed: 28 additions & 9 deletions

File tree

doc/api/vm.markdown

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ The options when creating a script are:
4141
- `cachedData`: an optional `Buffer` with V8's code cache data for the supplied
4242
source. When supplied `cachedDataRejected` value will be set to either
4343
`true` or `false` depending on acceptance of the data by V8.
44-
- `produceCachedData`: if `true` and no `cachedData` is present - a `Buffer`
45-
with V8's code cache data will be produced and stored in `cachedData` property
46-
of the returned `vm.Script` instance.
44+
- `produceCachedData`: if `true` and no `cachedData` is present - V8 tries to
45+
produce code cache data for `code`. Upon success, a `Buffer` with V8's code
46+
cache data will be produced and stored in `cachedData` property of the
47+
returned `vm.Script` instance. `cachedDataProduced` value will be set to
48+
either `true` or `false` depending on whether code cache data is produced
49+
successfully.
4750

4851
### script.runInContext(contextifiedSandbox[, options])
4952

src/env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace node {
7272
V(bytes_string, "bytes") \
7373
V(bytes_parsed_string, "bytesParsed") \
7474
V(cached_data_string, "cachedData") \
75+
V(cached_data_produced_string, "cachedDataProduced") \
7576
V(cached_data_rejected_string, "cachedDataRejected") \
7677
V(callback_string, "callback") \
7778
V(change_string, "change") \

src/node_contextify.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -545,11 +545,17 @@ class ContextifyScript : public BaseObject {
545545
Boolean::New(env->isolate(), source.GetCachedData()->rejected));
546546
} else if (compile_options == ScriptCompiler::kProduceCodeCache) {
547547
const ScriptCompiler::CachedData* cached_data = source.GetCachedData();
548-
MaybeLocal<Object> buf = Buffer::Copy(
549-
env,
550-
reinterpret_cast<const char*>(cached_data->data),
551-
cached_data->length);
552-
args.This()->Set(env->cached_data_string(), buf.ToLocalChecked());
548+
bool cached_data_produced = cached_data != nullptr;
549+
if (cached_data_produced) {
550+
MaybeLocal<Object> buf = Buffer::Copy(
551+
env,
552+
reinterpret_cast<const char*>(cached_data->data),
553+
cached_data->length);
554+
args.This()->Set(env->cached_data_string(), buf.ToLocalChecked());
555+
}
556+
args.This()->Set(
557+
env->cached_data_produced_string(),
558+
Boolean::New(env->isolate(), cached_data_produced));
553559
}
554560
}
555561

test/parallel/test-vm-cached-data.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function produce(source) {
1212
const script = new vm.Script(source, {
1313
produceCachedData: true
1414
});
15-
assert(script.cachedData instanceof Buffer);
15+
assert(!script.cachedDataProduced || script.cachedData instanceof Buffer);
1616

1717
return script.cachedData;
1818
}
@@ -31,6 +31,15 @@ function testProduceConsume() {
3131
}
3232
testProduceConsume();
3333

34+
function testProduceMultiple() {
35+
const source = getSource('original');
36+
37+
produce(source);
38+
produce(source);
39+
produce(source);
40+
}
41+
testProduceMultiple();
42+
3443
function testRejectInvalid() {
3544
const source = getSource('invalid');
3645

0 commit comments

Comments
 (0)