Browse Source

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: https://github.com/nodejs/node/pull/5343
Reviewed-By: Fedor Indutny <fedor@indutny.com>
process-exit-stdio-flushing
Jiho Choi 9 years ago
committed by Fedor Indutny
parent
commit
d5c04c34f1
  1. 9
      doc/api/vm.markdown
  2. 1
      src/env.h
  3. 16
      src/node_contextify.cc
  4. 11
      test/parallel/test-vm-cached-data.js

9
doc/api/vm.markdown

@ -41,9 +41,12 @@ The options when creating a script are:
- `cachedData`: an optional `Buffer` with V8's code cache data for the supplied
source. When supplied `cachedDataRejected` value will be set to either
`true` or `false` depending on acceptance of the data by V8.
- `produceCachedData`: if `true` and no `cachedData` is present - a `Buffer`
with V8's code cache data will be produced and stored in `cachedData` property
of the returned `vm.Script` instance.
- `produceCachedData`: if `true` and no `cachedData` is present - V8 tries to
produce code cache data for `code`. Upon success, a `Buffer` with V8's code
cache data will be produced and stored in `cachedData` property of the
returned `vm.Script` instance. `cachedDataProduced` value will be set to
either `true` or `false` depending on whether code cache data is produced
successfully.
### script.runInContext(contextifiedSandbox[, options])

1
src/env.h

@ -72,6 +72,7 @@ namespace node {
V(bytes_string, "bytes") \
V(bytes_parsed_string, "bytesParsed") \
V(cached_data_string, "cachedData") \
V(cached_data_produced_string, "cachedDataProduced") \
V(cached_data_rejected_string, "cachedDataRejected") \
V(callback_string, "callback") \
V(change_string, "change") \

16
src/node_contextify.cc

@ -545,11 +545,17 @@ class ContextifyScript : public BaseObject {
Boolean::New(env->isolate(), source.GetCachedData()->rejected));
} else if (compile_options == ScriptCompiler::kProduceCodeCache) {
const ScriptCompiler::CachedData* cached_data = source.GetCachedData();
MaybeLocal<Object> buf = Buffer::Copy(
env,
reinterpret_cast<const char*>(cached_data->data),
cached_data->length);
args.This()->Set(env->cached_data_string(), buf.ToLocalChecked());
bool cached_data_produced = cached_data != nullptr;
if (cached_data_produced) {
MaybeLocal<Object> buf = Buffer::Copy(
env,
reinterpret_cast<const char*>(cached_data->data),
cached_data->length);
args.This()->Set(env->cached_data_string(), buf.ToLocalChecked());
}
args.This()->Set(
env->cached_data_produced_string(),
Boolean::New(env->isolate(), cached_data_produced));
}
}

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

@ -12,7 +12,7 @@ function produce(source) {
const script = new vm.Script(source, {
produceCachedData: true
});
assert(script.cachedData instanceof Buffer);
assert(!script.cachedDataProduced || script.cachedData instanceof Buffer);
return script.cachedData;
}
@ -31,6 +31,15 @@ function testProduceConsume() {
}
testProduceConsume();
function testProduceMultiple() {
const source = getSource('original');
produce(source);
produce(source);
produce(source);
}
testProduceMultiple();
function testRejectInvalid() {
const source = getSource('invalid');

Loading…
Cancel
Save