vm: allow cachedData
to also be TypedArray|DataView
PR-URL: https://github.com/nodejs/node/pull/22921 Refs: https://github.com/nodejs/node/issues/1826 Refs: https://github.com/nodejs/node/pull/22921#issuecomment-422350213 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Denys Otrishko <shishugi@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
parent
74ba48294b
commit
65fe999ed7
@ -434,10 +434,10 @@ changes:
|
|||||||
in stack traces produced by this script.
|
in stack traces produced by this script.
|
||||||
* `columnOffset` {number} Specifies the column number offset that is displayed
|
* `columnOffset` {number} Specifies the column number offset that is displayed
|
||||||
in stack traces produced by this script.
|
in stack traces produced by this script.
|
||||||
* `cachedData` {Buffer} Provides an optional `Buffer` with V8's code cache
|
* `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
|
||||||
data for the supplied source. When supplied, the `cachedDataRejected` value
|
`TypedArray`, or `DataView` with V8's code cache data for the supplied
|
||||||
will be set to either `true` or `false` depending on acceptance of the data
|
source. When supplied, the `cachedDataRejected` value will be set to
|
||||||
by V8.
|
either `true` or `false` depending on acceptance of the data by V8.
|
||||||
* `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
|
* `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8
|
||||||
will attempt to produce code cache data for `code`. Upon success, a
|
will attempt to produce code cache data for `code`. Upon success, a
|
||||||
`Buffer` with V8's code cache data will be produced and stored in the
|
`Buffer` with V8's code cache data will be produced and stored in the
|
||||||
@ -669,8 +669,9 @@ added: v10.10.0
|
|||||||
in stack traces produced by this script. **Default:** `0`.
|
in stack traces produced by this script. **Default:** `0`.
|
||||||
* `columnOffset` {number} Specifies the column number offset that is displayed
|
* `columnOffset` {number} Specifies the column number offset that is displayed
|
||||||
in stack traces produced by this script. **Default:** `0`.
|
in stack traces produced by this script. **Default:** `0`.
|
||||||
* `cachedData` {Buffer} Provides an optional `Buffer` with V8's code cache
|
* `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or
|
||||||
data for the supplied source.
|
`TypedArray`, or `DataView` with V8's code cache data for the supplied
|
||||||
|
source.
|
||||||
* `produceCachedData` {boolean} Specifies whether to produce new cache data.
|
* `produceCachedData` {boolean} Specifies whether to produce new cache data.
|
||||||
**Default:** `false`.
|
**Default:** `false`.
|
||||||
* `parsingContext` {Object} The [contextified][] sandbox in which the said
|
* `parsingContext` {Object} The [contextified][] sandbox in which the said
|
||||||
|
15
lib/vm.js
15
lib/vm.js
@ -32,7 +32,7 @@ const {
|
|||||||
ERR_INVALID_ARG_TYPE,
|
ERR_INVALID_ARG_TYPE,
|
||||||
ERR_VM_MODULE_NOT_MODULE,
|
ERR_VM_MODULE_NOT_MODULE,
|
||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
const { isModuleNamespaceObject, isUint8Array } = require('util').types;
|
const { isModuleNamespaceObject, isArrayBufferView } = require('util').types;
|
||||||
const { validateInt32, validateUint32 } = require('internal/validators');
|
const { validateInt32, validateUint32 } = require('internal/validators');
|
||||||
const kParsingContext = Symbol('script parsing context');
|
const kParsingContext = Symbol('script parsing context');
|
||||||
|
|
||||||
@ -64,9 +64,12 @@ class Script extends ContextifyScript {
|
|||||||
}
|
}
|
||||||
validateInt32(lineOffset, 'options.lineOffset');
|
validateInt32(lineOffset, 'options.lineOffset');
|
||||||
validateInt32(columnOffset, 'options.columnOffset');
|
validateInt32(columnOffset, 'options.columnOffset');
|
||||||
if (cachedData !== undefined && !isUint8Array(cachedData)) {
|
if (cachedData !== undefined && !isArrayBufferView(cachedData)) {
|
||||||
throw new ERR_INVALID_ARG_TYPE('options.cachedData',
|
throw new ERR_INVALID_ARG_TYPE(
|
||||||
['Buffer', 'Uint8Array'], cachedData);
|
'options.cachedData',
|
||||||
|
['Buffer', 'TypedArray', 'DataView'],
|
||||||
|
cachedData
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (typeof produceCachedData !== 'boolean') {
|
if (typeof produceCachedData !== 'boolean') {
|
||||||
throw new ERR_INVALID_ARG_TYPE('options.produceCachedData', 'boolean',
|
throw new ERR_INVALID_ARG_TYPE('options.produceCachedData', 'boolean',
|
||||||
@ -346,10 +349,10 @@ function compileFunction(code, params, options = {}) {
|
|||||||
}
|
}
|
||||||
validateUint32(columnOffset, 'options.columnOffset');
|
validateUint32(columnOffset, 'options.columnOffset');
|
||||||
validateUint32(lineOffset, 'options.lineOffset');
|
validateUint32(lineOffset, 'options.lineOffset');
|
||||||
if (cachedData !== undefined && !isUint8Array(cachedData)) {
|
if (cachedData !== undefined && !isArrayBufferView(cachedData)) {
|
||||||
throw new ERR_INVALID_ARG_TYPE(
|
throw new ERR_INVALID_ARG_TYPE(
|
||||||
'options.cachedData',
|
'options.cachedData',
|
||||||
'Uint8Array',
|
['Buffer', 'TypedArray', 'DataView'],
|
||||||
cachedData
|
cachedData
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ namespace contextify {
|
|||||||
|
|
||||||
using v8::Array;
|
using v8::Array;
|
||||||
using v8::ArrayBuffer;
|
using v8::ArrayBuffer;
|
||||||
|
using v8::ArrayBufferView;
|
||||||
using v8::Boolean;
|
using v8::Boolean;
|
||||||
using v8::Context;
|
using v8::Context;
|
||||||
using v8::EscapableHandleScope;
|
using v8::EscapableHandleScope;
|
||||||
@ -64,7 +65,6 @@ using v8::String;
|
|||||||
using v8::Symbol;
|
using v8::Symbol;
|
||||||
using v8::TryCatch;
|
using v8::TryCatch;
|
||||||
using v8::Uint32;
|
using v8::Uint32;
|
||||||
using v8::Uint8Array;
|
|
||||||
using v8::UnboundScript;
|
using v8::UnboundScript;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
using v8::WeakCallbackInfo;
|
using v8::WeakCallbackInfo;
|
||||||
@ -629,7 +629,7 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
Local<Integer> line_offset;
|
Local<Integer> line_offset;
|
||||||
Local<Integer> column_offset;
|
Local<Integer> column_offset;
|
||||||
Local<Uint8Array> cached_data_buf;
|
Local<ArrayBufferView> cached_data_buf;
|
||||||
bool produce_cached_data = false;
|
bool produce_cached_data = false;
|
||||||
Local<Context> parsing_context = context;
|
Local<Context> parsing_context = context;
|
||||||
|
|
||||||
@ -642,8 +642,8 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|||||||
CHECK(args[3]->IsNumber());
|
CHECK(args[3]->IsNumber());
|
||||||
column_offset = args[3].As<Integer>();
|
column_offset = args[3].As<Integer>();
|
||||||
if (!args[4]->IsUndefined()) {
|
if (!args[4]->IsUndefined()) {
|
||||||
CHECK(args[4]->IsUint8Array());
|
CHECK(args[4]->IsArrayBufferView());
|
||||||
cached_data_buf = args[4].As<Uint8Array>();
|
cached_data_buf = args[4].As<ArrayBufferView>();
|
||||||
}
|
}
|
||||||
CHECK(args[5]->IsBoolean());
|
CHECK(args[5]->IsBoolean());
|
||||||
produce_cached_data = args[5]->IsTrue();
|
produce_cached_data = args[5]->IsTrue();
|
||||||
@ -994,10 +994,10 @@ void ContextifyContext::CompileFunction(
|
|||||||
Local<Integer> column_offset = args[3].As<Integer>();
|
Local<Integer> column_offset = args[3].As<Integer>();
|
||||||
|
|
||||||
// Argument 5: cached data (optional)
|
// Argument 5: cached data (optional)
|
||||||
Local<Uint8Array> cached_data_buf;
|
Local<ArrayBufferView> cached_data_buf;
|
||||||
if (!args[4]->IsUndefined()) {
|
if (!args[4]->IsUndefined()) {
|
||||||
CHECK(args[4]->IsUint8Array());
|
CHECK(args[4]->IsArrayBufferView());
|
||||||
cached_data_buf = args[4].As<Uint8Array>();
|
cached_data_buf = args[4].As<ArrayBufferView>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Argument 6: produce cache data
|
// Argument 6: produce cache data
|
||||||
|
@ -178,18 +178,20 @@ const vm = require('vm');
|
|||||||
'filename': 'string',
|
'filename': 'string',
|
||||||
'columnOffset': 'number',
|
'columnOffset': 'number',
|
||||||
'lineOffset': 'number',
|
'lineOffset': 'number',
|
||||||
'cachedData': 'Uint8Array',
|
'cachedData': 'Buffer, TypedArray, or DataView',
|
||||||
'produceCachedData': 'boolean',
|
'produceCachedData': 'boolean',
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const option in optionTypes) {
|
for (const option in optionTypes) {
|
||||||
|
const typeErrorMessage = `The "options.${option}" property must be ` +
|
||||||
|
`${option === 'cachedData' ? 'one of' : 'of'} type`;
|
||||||
common.expectsError(() => {
|
common.expectsError(() => {
|
||||||
vm.compileFunction('', undefined, { [option]: null });
|
vm.compileFunction('', undefined, { [option]: null });
|
||||||
}, {
|
}, {
|
||||||
type: TypeError,
|
type: TypeError,
|
||||||
code: 'ERR_INVALID_ARG_TYPE',
|
code: 'ERR_INVALID_ARG_TYPE',
|
||||||
message: `The "options.${option}" property must be of type ` +
|
message: typeErrorMessage +
|
||||||
`${optionTypes[option]}. Received type object`
|
` ${optionTypes[option]}. Received type object`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,14 @@ function testProduceConsume() {
|
|||||||
|
|
||||||
const data = produce(source);
|
const data = produce(source);
|
||||||
|
|
||||||
|
for (const cachedData of common.getArrayBufferViews(data)) {
|
||||||
// It should consume code cache
|
// It should consume code cache
|
||||||
const script = new vm.Script(source, {
|
const script = new vm.Script(source, {
|
||||||
cachedData: data
|
cachedData
|
||||||
});
|
});
|
||||||
assert(!script.cachedDataRejected);
|
assert(!script.cachedDataRejected);
|
||||||
assert.strictEqual(script.runInThisContext()(), 'original');
|
assert.strictEqual(script.runInThisContext()(), 'original');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
testProduceConsume();
|
testProduceConsume();
|
||||||
|
|
||||||
@ -91,5 +93,5 @@ common.expectsError(() => {
|
|||||||
}, {
|
}, {
|
||||||
code: 'ERR_INVALID_ARG_TYPE',
|
code: 'ERR_INVALID_ARG_TYPE',
|
||||||
type: TypeError,
|
type: TypeError,
|
||||||
message: /must be one of type Buffer or Uint8Array/
|
message: /must be one of type Buffer, TypedArray, or DataView/
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user