From 1abbe0a2123e8333922894258389c2d5c1568472 Mon Sep 17 00:00:00 2001 From: Ujjwal Sharma Date: Thu, 28 Jun 2018 12:05:19 +0530 Subject: vm: add bindings for v8::CompileFunctionInContext Adds a method compileFunction to the vm module, which serves as a binding for v8::CompileFunctionInContext with appropriate args for specifying the details, and provide params for the wrapper. Eventually, we would be changing Module._compile to use this internally over the standard Module.wrap PR-URL: https://github.com/nodejs/node/pull/21571 Reviewed-By: Anna Henningsen Reviewed-By: Tiancheng "Timothy" Gu Reviewed-By: John-David Dalton Reviewed-By: Gus Caplan Reviewed-By: James M Snell --- lib/vm.js | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'lib/vm.js') diff --git a/lib/vm.js b/lib/vm.js index b80cd98dee..6ec40f9bca 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -26,12 +26,17 @@ const { ContextifyScript, makeContext, isContext: _isContext, + compileFunction: _compileFunction } = internalBinding('contextify'); + const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; const { isUint8Array } = require('internal/util/types'); const { validateInt32, validateUint32 } = require('internal/validators'); const kParsingContext = Symbol('script parsing context'); +const ArrayForEach = Function.call.bind(Array.prototype.forEach); +const ArrayIsArray = Array.isArray; + class Script extends ContextifyScript { constructor(code, options = {}) { code = `${code}`; @@ -286,6 +291,94 @@ function runInThisContext(code, options) { return createScript(code, options).runInThisContext(options); } +function compileFunction(code, params, options = {}) { + if (typeof code !== 'string') { + throw new ERR_INVALID_ARG_TYPE('code', 'string', code); + } + if (params !== undefined) { + if (!ArrayIsArray(params)) { + throw new ERR_INVALID_ARG_TYPE('params', 'Array', params); + } + ArrayForEach(params, (param, i) => { + if (typeof param !== 'string') { + throw new ERR_INVALID_ARG_TYPE(`params[${i}]`, 'string', param); + } + }); + } + + const { + filename = '', + columnOffset = 0, + lineOffset = 0, + cachedData = undefined, + produceCachedData = false, + parsingContext = undefined, + contextExtensions = [], + } = options; + + if (typeof filename !== 'string') { + throw new ERR_INVALID_ARG_TYPE('options.filename', 'string', filename); + } + validateUint32(columnOffset, 'options.columnOffset'); + validateUint32(lineOffset, 'options.lineOffset'); + if (cachedData !== undefined && !isUint8Array(cachedData)) { + throw new ERR_INVALID_ARG_TYPE( + 'options.cachedData', + 'Uint8Array', + cachedData + ); + } + if (typeof produceCachedData !== 'boolean') { + throw new ERR_INVALID_ARG_TYPE( + 'options.produceCachedData', + 'boolean', + produceCachedData + ); + } + if (parsingContext !== undefined) { + if ( + typeof parsingContext !== 'object' || + parsingContext === null || + !isContext(parsingContext) + ) { + throw new ERR_INVALID_ARG_TYPE( + 'options.parsingContext', + 'Context', + parsingContext + ); + } + } + if (!ArrayIsArray(contextExtensions)) { + throw new ERR_INVALID_ARG_TYPE( + 'options.contextExtensions', + 'Array', + contextExtensions + ); + } + ArrayForEach(contextExtensions, (extension, i) => { + if (typeof extension !== 'object') { + throw new ERR_INVALID_ARG_TYPE( + `options.contextExtensions[${i}]`, + 'object', + extension + ); + } + }); + + return _compileFunction( + code, + filename, + lineOffset, + columnOffset, + cachedData, + produceCachedData, + parsingContext, + contextExtensions, + params + ); +} + + module.exports = { Script, createContext, @@ -294,6 +387,7 @@ module.exports = { runInNewContext, runInThisContext, isContext, + compileFunction, }; if (process.binding('config').experimentalVMModules) { -- cgit v1.2.3