git ssb

0+

cel-desktop / ssb-pkg



Tree: e1a1630f31c55420ca08a2a8e36296e3c202f1b1

Files: e1a1630f31c55420ca08a2a8e36296e3c202f1b1 / lib / fabricator.js

4407 bytesRaw
1import { log } from './log.js';
2import { spawn } from 'child_process';
3
4const script = `
5 var vm = require('vm');
6 var module = require('module');
7 var stdin = Buffer.alloc(0);
8 process.stdin.on('data', function (data) {
9 stdin = Buffer.concat([ stdin, data ]);
10 if (stdin.length >= 4) {
11 var sizeOfSnap = stdin.readInt32LE(0);
12 if (stdin.length >= 4 + sizeOfSnap + 4) {
13 var sizeOfBody = stdin.readInt32LE(4 + sizeOfSnap);
14 if (stdin.length >= 4 + sizeOfSnap + 4 + sizeOfBody) {
15 var snap = stdin.toString('utf8', 4, 4 + sizeOfSnap);
16 var body = Buffer.alloc(sizeOfBody);
17 var startOfBody = 4 + sizeOfSnap + 4;
18 stdin.copy(body, 0, startOfBody, startOfBody + sizeOfBody);
19 stdin = Buffer.alloc(0);
20 var code = module.wrap(body);
21 var s = new vm.Script(code, {
22 filename: snap,
23 produceCachedData: true,
24 sourceless: true
25 });
26 if (!s.cachedDataProduced) {
27 console.error('Pkg: Cached data not produced.');
28 process.exit(2);
29 }
30 var h = Buffer.alloc(4);
31 var b = s.cachedData;
32 h.writeInt32LE(b.length, 0);
33 process.stdout.write(h);
34 process.stdout.write(b);
35 }
36 }
37 }
38 });
39 process.stdin.resume();
40`;
41
42const children = {};
43
44export function fabricate (bakes, fabricator, snap, body, cb) {
45 bakes = bakes.filter(function (bake) {
46 // list of bakes that don't influence the bytecode
47 const bake2 = bake.replace(/_/g, '-');
48 return ![ '--prof', '--v8-options', '--trace-opt', '--trace-deopt' ].includes(bake2);
49 });
50
51 const cmd = fabricator.binaryPath;
52 const key = JSON.stringify([ cmd, bakes ]);
53 let child = children[key];
54
55 if (!child) {
56 const stderr = log.debugMode ? process.stdout : 'ignore';
57 child = children[key] = spawn(
58 cmd, bakes.concat('-e', script),
59 { stdio: [ 'pipe', 'pipe', stderr ],
60 env: { PKG_EXECPATH: 'PKG_INVOKE_NODEJS' } }
61 );
62 }
63
64 function kill () {
65 delete children[key];
66 child.kill();
67 }
68
69 let stdout = Buffer.alloc(0);
70
71 function onError (error) {
72 removeListeners();
73 kill();
74 cb(new Error(`Failed to make bytecode ${fabricator.nodeRange}-${fabricator.arch} for file ${snap} error (${error.message})`));
75 }
76
77 function onClose (code) {
78 removeListeners();
79 kill();
80 if (code !== 0) {
81 return cb(new Error(`Failed to make bytecode ${fabricator.nodeRange}-${fabricator.arch} for file ${snap}`));
82 } else {
83 console.log(stdout.toString());
84 return cb(new Error(`${cmd} closed unexpectedly`));
85 }
86 }
87
88 function onData (data) {
89 stdout = Buffer.concat([ stdout, data ]);
90 if (stdout.length >= 4) {
91 const sizeOfBlob = stdout.readInt32LE(0);
92 if (stdout.length >= 4 + sizeOfBlob) {
93 const blob = Buffer.alloc(sizeOfBlob);
94 stdout.copy(blob, 0, 4, 4 + sizeOfBlob);
95 removeListeners();
96 return cb(undefined, blob);
97 }
98 }
99 }
100
101 child.on('error', onError);
102 child.on('close', onClose);
103 child.stdin.on('error', onError);
104 child.stdout.on('error', onError);
105 child.stdout.on('data', onData);
106 function removeListeners () {
107 child.removeListener('error', onError);
108 child.removeListener('close', onClose);
109 child.stdin.removeListener('error', onError);
110 child.stdout.removeListener('error', onError);
111 child.stdout.removeListener('data', onData);
112 }
113
114 const h = Buffer.alloc(4);
115 let b = Buffer.from(snap);
116 h.writeInt32LE(b.length, 0);
117 child.stdin.write(h);
118 child.stdin.write(b);
119 b = body;
120 h.writeInt32LE(b.length, 0);
121 child.stdin.write(h);
122 child.stdin.write(b);
123}
124
125export function fabricateTwice (bakes, fabricator, snap, body, cb) {
126 fabricate(bakes, fabricator, snap, body, (error, buffer) => {
127 // node0 can not produce second time, even if first time produced fine,
128 // probably because of 'filename' cache. also, there are wierd cases
129 // when node4 can not compile as well, for example file 'lib/js-yaml/dumper.js'
130 // of package js-yaml@3.9.0 does not get bytecode second time on node4-win-x64
131 if (error) return fabricate(bakes, fabricator, snap, body, cb);
132 cb(undefined, buffer);
133 });
134}
135
136export function shutdown () {
137 for (const key in children) {
138 const child = children[key];
139 delete children[key];
140 child.kill();
141 }
142}
143

Built with git-ssb-web