const vm = require('vm');
const v8 = require('v8');
const zlib = require('zlib');
const fs = require('fs');
const path = require('path');
const Module = require('module');
v8.setFlagsFromString('--no-lazy');
v8.setFlagsFromString('--no-flush-bytecode');
global.generateScript=function(cachedData, filename) {
cachedData = zlib.brotliDecompressSync(cachedData);
fixBytecode(cachedData);
const length = readSourceHash(cachedData);
let dummyCode = '';
if (length > 1) {
dummyCode = '"' + '\u200b'.repeat(length - 2) + '"';
}
const script = new vm.Script(dummyCode, {
cachedData,
filename
});
if (script.cachedDataRejected) {
throw new Error('');
}
return script;
}
global.compileCode = function(javascriptCode, compress) {
const script = new vm.Script(javascriptCode, {
produceCachedData: true
});
let bytecodeBuffer = (script.createCachedData && script.createCachedData.call) ?
script.createCachedData() :
script.cachedData;
if (compress) bytecodeBuffer = zlib.brotliCompressSync(bytecodeBuffer);
return bytecodeBuffer;
};
global.fixBytecode = function(bytecodeBuffer) {
const dummyBytecode = compileCode('');
dummyBytecode.subarray(12, 16).copy(bytecodeBuffer, 12);
};
global.readSourceHash = function(bytecodeBuffer) {
return bytecodeBuffer.subarray(8, 12).reduce((sum, number, power) => sum += number * Math.pow(256, power), 0);
};
try {
Module._extensions['.jsc'] = function(fileModule, filename) {
const data = fs.readFileSync(filename, 'utf8')
const bytecodeBuffer = Buffer.from(data, 'base64');
const script = generateScript(bytecodeBuffer, filename);
function require(id) {
return fileModule.require(id);
}
require.resolve = function(request, options) {
return Module._resolveFilename(request, fileModule, false, options);
};
if (process.main) {
require.main = process.main;
}
require.extensions = Module._extensions;
require.cache = Module._cache;
const compiledWrapper = script.runInThisContext({
filename: filename,
lineOffset: 0,
columnOffset: 0,
displayErrors: true
});
const dirname = path.dirname(filename);
const args = [
fileModule.exports, require, fileModule, filename, dirname, process, global
];
return compiledWrapper.apply(fileModule.exports, args);
};
} catch (ex) {
console.error('xrequire:' + ex.message);
}
require("${codeScript}")