From 87660c3682d306e7b7ca116e170ba029129e69b9 Mon Sep 17 00:00:00 2001 From: Jared Allard Date: Thu, 28 Jan 2016 14:25:31 -0800 Subject: [PATCH] exe: fixes #168. Implements package.json nexe.runtime.js-flags for v8 flags. --- .gitignore | 3 +- .npmignore | 4 +- lib/exe.js | 114 +++++++++++++++++++++++++++++++++-- test/flags-test/index.js | 13 ++++ test/flags-test/package.json | 15 +++++ 5 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 test/flags-test/index.js create mode 100644 test/flags-test/package.json diff --git a/.gitignore b/.gitignore index 29c08d7..a60bd28 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ src nexe.exe nexe npm-debug.log -# test/**/src +test/**/src test/**/out.nex +test/**/test.nex diff --git a/.npmignore b/.npmignore index c65cac8..e846e54 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,4 @@ node_modules test/**/src -test/**/*.exe -test/**/*.nexe +test/**/*-test +test/**/*.nex diff --git a/lib/exe.js b/lib/exe.js index 80d1a10..8063002 100644 --- a/lib/exe.js +++ b/lib/exe.js @@ -186,6 +186,14 @@ exports.compile = function (options, complete) { } }, + function monkeyPatchv8FlagsCc (next) { + if(options.jsFlags) { + return _monkeyPatchv8FlagsCc(nodeCompiler, options, next); + } + + return next(); + }, + /** * monkeypatch child_process.js so nexejs knows when it is a forked process */ @@ -434,9 +442,6 @@ function _getNodeCompiler (nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complet var conf = [cfg]; - console.log(isPy); - console.log(dir); - if(isPy !== "python") { conf = [conf].concat(nodeConfigureArgs); } @@ -673,6 +678,103 @@ function _monkeyPatchMainCc(compiler, complete) { } /** + * Patch flags.cc from deps/v8/src to use hard-coded flags. + * this function is very closely ready to accept custom injection code. + **/ +function _monkeyPatchv8FlagsCc(compiler, options, complete) { + var mainPath = path.join(compiler.dir, "deps/v8/src", "flags.cc"); + + fs.readFile(mainPath, {encoding: 'utf8'}, function(err, contents) { + if(err) { + return _log('error', 'failed to read', mainPath); + } + + // Super simple injection here. Perhaps make it an array at somepoint? + var injection = '\ +const char* nexevargs = "{{args}}";\n\ +int nexevargslen = strlen(nexevargs);\n\ +SetFlagsFromString(nexevargs, nexevargslen);\n\ +'; + + var injectionSplit = injection.split('\n'); + var injectionLength = injectionSplit.length; + var contentsSplit = contents.split('\n'); + var contentsLength = contentsSplit.length; + var lastInjectionLine = injectionSplit[injectionLength-2]; + + var lineToInjectAfter = contentsSplit.indexOf(' ComputeFlagListHash();'); + var haveWeInjectedBefore = contentsSplit.indexOf(lastInjectionLine); + + var lineInjectDifference = contentsLength - lineToInjectAfter; + + // this is debug, comment out. + // _log('v8 injection is', injectionLength, 'newlines long'); + // _log('v8 flags source is', contentsLength, 'newlines long'); + + // console.log(finalContents) + + var finalContents, + dontCombine; + + if(lineToInjectAfter !== -1 && haveWeInjectedBefore === -1) { + _log('injecting v8 args c++'); + + // super debug + // _log('v8 injection determined by', lastInjectionLine); + // _log('v8 inject after line', lineToInjectAfter); + // _log('v8 inject needs to shift', lineInjectDifference, 'amount of lines by', injectionLength); + + // compute out the amount of space we'll need in this. + var startShiftLine = contentsLength-1; // minus one to make up for 0 arg line. + var endShiftLine = lineToInjectAfter; + var injectRoom = injectionLength-1; + + injectionSplit[0] = injectionSplit[0].replace('{{args}}', options.jsFlags); + + console.log(startShiftLine, endShiftLine); + + for (var i = startShiftLine; i !== endShiftLine; i--) { + contentsSplit[i+injectRoom] = contentsSplit[i]; + contentsSplit[i] = ''; + } + + var injectionPos = 0; + for(var i = 0; i !== injectionLength-1; i++) { + contentsSplit[(lineToInjectAfter+1)+injectionPos] = injectionSplit[injectionPos]; + injectionPos++; + } + } else if(lineToInjectAfter !== -1 && haveWeInjectedBefore !== -1) { + _log('re-injecting v8 args'); + + dontCombine = true; + finalContents = contentsSplit.join('\n'); + finalContents = finalContents.replace(/const char\* nexevargs = "[A-Z\-\_]*";/gi, + 'const char* nexevargs = "'+options.jsFlags+'";'); + } else { + _log('warn', 'failed to find a suitable injection point for v8 args.', + 'File a bug report with the node version and log.'); + + _log('lineToInjectAfter='+lineToInjectAfter, 'haveWeInjectedBefore='+haveWeInjectedBefore); + return process.exit(1); + } + + if(!dontCombine) { + finalContents = contentsSplit.join('\n'); + } + + fs.writeFile(mainPath, finalContents, {encoding: 'utf8'}, function(err) { + if(err) { + _log('error', 'failed to write to', mainPath); + return process.exit(1); + } + + return complete(); + }) + }); +} + +/** + * Get the first directory of a string. */ function _getFirstDirectory (dir) { @@ -687,6 +789,7 @@ function _getFirstDirectory (dir) { } /** + * Log the progress of a request object. */ function _logProgress (req) { @@ -698,7 +801,7 @@ function _logProgress (req) { complete: "=", incomplete: " ", total: len, - width: ((isWin) ? 100 : process.stdout.columns - 2) // windows doesn't output colums correctly + width: 100 // just use 100 }); req.on("data", function (chunk) { @@ -747,12 +850,13 @@ exports.package = function(path, options) { var obj = { input: (_package.nexe.input || options.i), output: (_package.nexe.output || options.o), - flags: (_package.nexe.runtime.ignoreFlags || options.f), + flags: (_package.nexe.runtime.ignoreFlags || (options.f || false)), nodeMakeArgs: (_package.nexe.runtime.nodeMakeArgs || []), resourceFiles: (_package.nexe.resourceFiles), nodeVersion: (_package.nexe.runtime.version || options.r), nodeConfigureArgs: (_package.nexe.runtime.nodeConfigureArgs || []), nodeMakeArgs: (_package.nexe.runtime.nodeMakeArgs || []), + jsFlags: (_package.nexe.runtime['js-flags'] || false), python: (_package.nexe.python || options.p), nodeTempDir: (_package.nexe.temp || options.t), framework: (_package.nexe.runtime.framework || options.f) diff --git a/test/flags-test/index.js b/test/flags-test/index.js new file mode 100644 index 0000000..71bd240 --- /dev/null +++ b/test/flags-test/index.js @@ -0,0 +1,13 @@ +/** + * Test to verify if we support strict mode (flags) + * + * @author Jared Allard + * @version 0.0.1 + * @license MIT + **/ + + // "use strict"; w/o --use_strict + + var isStrict = (function() { return !this; })(); + + console.log('test:strict-mode:status =', isStrict); diff --git a/test/flags-test/package.json b/test/flags-test/package.json new file mode 100644 index 0000000..0f05be8 --- /dev/null +++ b/test/flags-test/package.json @@ -0,0 +1,15 @@ +{ + "name": "flags-test", + "nexe": { + "input": "./index.js", + "output": "test.nex^$", + "temp": "src", + "runtime": { + "framework": "node", + "version": "5.5.0", + "ignoreFlags": false, + "js-flags": "--use_strict", + "node-args": "" + } + } +}