#!/usr/bin/env node var spawn = require('child_process').spawn; var node = process.execPath || process.argv[0]; var HG = '--harmony_generators'; var regenerator = require('regenerator') // first check if the current node executable has "Generators". // if not, fall back to facebook/regenerator for Generators support. hasGenerators(function (err, has) { if (err) throw err; // build up the node(1) arguments for Generator support var argv = (process.execArgv || []).slice(0); // process the regular arguments. if any of them begin with a hyphen (-) then // it's a switch and should be added *before* the ENTRY_POINT in the argv... var argsStart = 2; for (var i = argsStart; i < process.argv.length; i++) { var arg = process.argv[i]; var isFlag = '-' == arg[0]; if (isFlag) { if (!/^--harmony[_-]generators$/.test(arg)) { argv.push(arg); } argsStart++; if (/^-[ep]$/.test(arg)) { // handle gnode -e|-p "console.log('script')" var code = process.argv[i + 1] if (!has) { code = regenerator.compile(code, { includeRuntime: true }).code; } argv.push(code) // skip arg, we just processed it i++ } } else { // must be the script file break; } } if (has && -1 == argv.indexOf(HG) && -1 == argv.indexOf('--harmony-generators')) { // if the node process natively supports Generators, // then add the --harmony_generators flag argv.push(HG); } if (!has) { // no Generator support, then we need to load fallback.js first argv.push(require('path').resolve(__dirname, '..', 'fallback.js')); // store a reference to the entry point, so that fallback.js can pick it up if (process.argv.length > argsStart) { process.env.GNODE_ENTRY_POINT = process.argv[argsStart]; } argsStart++; } // add the rest of the arguments specified by the user if (process.argv.length >= argsStart) { argv.push.apply(argv, process.argv.slice(argsStart)); } if (parseInt(process.env.GNODE_PRINT_ARGS, 10)) { // print out the arguments that will be passed in for debugging purposes console.error(argv); } var opts = { customFds: [ 0, 1, 2 ], stdio: 'inherit' }; // spawn a new node process with the necessary flags var child = spawn(node, argv, opts); child.on('exit', onexit); }); /** * Main node subprocess "exit" event handler. * Proxies the exit code up to this process. * * @api private */ function onexit(code, signal) { if (signal) { process.kill(process.pid, signal); } else if (0 !== code) { if (null == process.exitCode) { // old node, no `process.exitCode` support... process.exit(code); } else { // newer node, we can set `process.exitCode` // and let the process exit naturally process.exitCode = code; } } } /** * Async function that returns `true`/`false` for if Generators are * supported by V8. * * @api private */ function hasGenerators (fn) { var cp = spawn(node, [ '--v8-options' ]); var data = ''; function onerror (e) { fn(e); } function ondata (b) { data += b; } function onend () { cp.removeListener('error', onerror); var has = -1 != data.indexOf(HG); fn(null, has); } cp.on('error', onerror); cp.stdout.setEncoding('utf8'); cp.stdout.on('data', ondata); cp.stdout.on('end', onend); }