UNPKG

3.46 kBPlain TextView Raw
1#!/usr/bin/env node
2
3var spawn = require('child_process').spawn;
4var node = process.execPath || process.argv[0];
5var HG = '--harmony_generators';
6
7var regenerator = require('regenerator')
8
9// first check if the current node executable has "Generators".
10// if not, fall back to facebook/regenerator for Generators support.
11hasGenerators(function (err, has) {
12 if (err) throw err;
13
14 // build up the node(1) arguments for Generator support
15 var argv = (process.execArgv || []).slice(0);
16
17 // process the regular arguments. if any of them begin with a hyphen (-) then
18 // it's a switch and should be added *before* the ENTRY_POINT in the argv...
19 var argsStart = 2;
20 for (var i = argsStart; i < process.argv.length; i++) {
21 var arg = process.argv[i];
22 var isFlag = '-' == arg[0];
23 if (isFlag) {
24 if (!/^--harmony[_-]generators$/.test(arg)) {
25 argv.push(arg);
26 }
27
28 argsStart++;
29
30 if (/^-[ep]$/.test(arg)) {
31 // handle gnode -e|-p "console.log('script')"
32 var code = process.argv[i + 1]
33 if (!has) {
34 code = regenerator.compile(code, {
35 includeRuntime: true
36 }).code;
37 }
38 argv.push(code)
39 // skip arg, we just processed it
40 i++
41 }
42 } else {
43 // must be the script file
44 break;
45 }
46 }
47
48 if (has && -1 == argv.indexOf(HG) && -1 == argv.indexOf('--harmony-generators')) {
49 // if the node process natively supports Generators,
50 // then add the --harmony_generators flag
51 argv.push(HG);
52 }
53
54 if (!has) {
55 // no Generator support, then we need to load fallback.js first
56 argv.push(require('path').resolve(__dirname, '..', 'fallback.js'));
57
58 // store a reference to the entry point, so that fallback.js can pick it up
59 if (process.argv.length > argsStart) {
60 process.env.GNODE_ENTRY_POINT = process.argv[argsStart];
61 }
62
63 argsStart++;
64 }
65
66 // add the rest of the arguments specified by the user
67 if (process.argv.length >= argsStart) {
68 argv.push.apply(argv, process.argv.slice(argsStart));
69 }
70
71 if (parseInt(process.env.GNODE_PRINT_ARGS, 10)) {
72 // print out the arguments that will be passed in for debugging purposes
73 console.error(argv);
74 }
75
76 var opts = {
77 customFds: [ 0, 1, 2 ],
78 stdio: 'inherit'
79 };
80
81 // spawn a new node process with the necessary flags
82 var child = spawn(node, argv, opts);
83 child.on('exit', onexit);
84});
85
86/**
87 * Main node subprocess "exit" event handler.
88 * Proxies the exit code up to this process.
89 *
90 * @api private
91 */
92
93function onexit(code, signal) {
94 if (signal) {
95 process.kill(process.pid, signal);
96 } else if (0 !== code) {
97 if (null == process.exitCode) {
98 // old node, no `process.exitCode` support...
99 process.exit(code);
100 } else {
101 // newer node, we can set `process.exitCode`
102 // and let the process exit naturally
103 process.exitCode = code;
104 }
105 }
106}
107
108/**
109 * Async function that returns `true`/`false` for if Generators are
110 * supported by V8.
111 *
112 * @api private
113 */
114
115function hasGenerators (fn) {
116 var cp = spawn(node, [ '--v8-options' ]);
117 var data = '';
118
119 function onerror (e) {
120 fn(e);
121 }
122 function ondata (b) {
123 data += b;
124 }
125 function onend () {
126 cp.removeListener('error', onerror);
127 var has = -1 != data.indexOf(HG);
128 fn(null, has);
129 }
130
131 cp.on('error', onerror);
132 cp.stdout.setEncoding('utf8');
133 cp.stdout.on('data', ondata);
134 cp.stdout.on('end', onend);
135}