mirror of
https://git.mirrors.martin98.com/https://github.com/cilame/v_jstools
synced 2025-08-14 13:46:00 +08:00
add
This commit is contained in:
parent
748446be0d
commit
5d91a5dc0b
108
tools/bytejs.js
Normal file
108
tools/bytejs.js
Normal file
@ -0,0 +1,108 @@
|
||||
// makebytejs.js
|
||||
const vm = require('vm');
|
||||
const fs = require('fs').promises;
|
||||
const _module = require('module');
|
||||
const v8 = require('v8');
|
||||
v8.setFlagsFromString('--no-lazy');
|
||||
|
||||
async function compileFile(filePath) {
|
||||
const code = await fs.readFile(filePath, 'utf-8');
|
||||
const script = new vm.Script(_module.wrap(code));
|
||||
const bytecode = script.createCachedData();
|
||||
await fs.writeFile(filePath.replace(/\.js$/i, '.bytecode'), bytecode);
|
||||
}
|
||||
compileFile('./test.js');
|
||||
|
||||
|
||||
|
||||
// runbytejs.js
|
||||
const _module = require('module');
|
||||
const path = require('path');
|
||||
const fs = require('fs')
|
||||
const vm = require('vm');
|
||||
const v8 = require('v8');
|
||||
v8.setFlagsFromString('--no-flush-bytecode');
|
||||
function validateString(value, name) {
|
||||
if (typeof value !== 'string') {
|
||||
throw new Error(`${name} is not string`);
|
||||
}
|
||||
}
|
||||
function makeRequireFunction(mod) {
|
||||
const Module = mod.constructor;
|
||||
const require = function require(path) {
|
||||
return mod.require(path);
|
||||
};
|
||||
require.resolve = function resolve(request, options) {
|
||||
validateString(request, 'request');
|
||||
return Module._resolveFilename(request, mod, false, options);
|
||||
}
|
||||
require.resolve.paths = function paths(request) {
|
||||
validateString(request, 'request');
|
||||
return Module._resolveLookupPaths(request, mod);
|
||||
};
|
||||
require.main = process.mainModule;
|
||||
require.extensions = Module._extensions;
|
||||
require.cache = Module._cache;
|
||||
return require;
|
||||
}
|
||||
const HeaderOffsetMap = {
|
||||
'magic': 0,
|
||||
'version_hash': 4,
|
||||
'source_hash': 8,
|
||||
'flag_hash': 12
|
||||
};
|
||||
let _flag_buf;
|
||||
function getFlagBuf() {
|
||||
if (!_flag_buf) {
|
||||
const script = new vm.Script("");
|
||||
_flag_buf = getHeader(script.createCachedData(), 'flag_hash');
|
||||
}
|
||||
return _flag_buf;
|
||||
}
|
||||
function getHeader(buffer, type) {
|
||||
const offset = HeaderOffsetMap[type];
|
||||
return buffer.slice(offset, offset + 4);
|
||||
}
|
||||
function setHeader(buffer, type, vBuffer) {
|
||||
vBuffer.copy(buffer, HeaderOffsetMap[type]);
|
||||
}
|
||||
function buf2num(buf) {
|
||||
// 注意字节序问题
|
||||
let ret = 0;
|
||||
ret |= buf[3] << 24;
|
||||
ret |= buf[2] << 16;
|
||||
ret |= buf[1] << 8;
|
||||
ret |= buf[0];
|
||||
return ret;
|
||||
}
|
||||
function loadBytecode(filePath) {
|
||||
const bytecode = fs.readFileSync(filePath, null);
|
||||
console.log(bytecode.toString('latin1'))
|
||||
setHeader(bytecode, 'flag_hash', getFlagBuf());
|
||||
const sourceHash = buf2num(getHeader(bytecode, 'source_hash'));
|
||||
const script = new vm.Script(' '.repeat(sourceHash), {
|
||||
filename: filePath,
|
||||
cachedData: bytecode,
|
||||
lineOffset: 0,
|
||||
displayErrors: true
|
||||
});
|
||||
if (script.cachedDataRejected) {
|
||||
throw new Error('something is wrong');
|
||||
}
|
||||
return script;
|
||||
}
|
||||
_module._extensions['.bytecode'] = function (module, filename) {
|
||||
const script = loadBytecode(filename, false);
|
||||
const wrapperFn = script.runInThisContext({
|
||||
filename: filename,
|
||||
displayErrors: true,
|
||||
lineOffset: 0,
|
||||
columnOffset: 0,
|
||||
});
|
||||
const require = makeRequireFunction(module);
|
||||
wrapperFn.bind(module.exports)(module.exports, require, module, filename, path.dirname(filename));
|
||||
}
|
||||
|
||||
require('./test.bytecode')
|
||||
|
||||
console.log(window.top == window.self)
|
Loading…
x
Reference in New Issue
Block a user