CodHavokASM/asm/disassembler.js

131 lines
3.9 KiB
JavaScript
Raw Permalink Normal View History

2018-08-14 12:42:05 +00:00
const consts = require("./../constants.js");
2019-11-01 07:49:22 +00:00
const insts = require("./../instructions/instructions.js");
2024-07-07 11:41:36 +00:00
const decoder = require("./../instructions/instructionDecoder.js");
2018-08-14 12:42:05 +00:00
const fmt = require("util").format;
function append(_, level, str) {
var a = "";
for (var i = 0; i < level; i ++)
a += " ";
_.msg += a + str + "\n";
}
function dmpConstants(_, level, constants) {
append(_, level, "START_CONSTANTS");
level++;
constants.objs.forEach((obj) => {
2018-08-14 19:01:46 +00:00
append(_, level, fmt("%s \t%s", obj.tname, obj.toString()));
2018-08-14 12:42:05 +00:00
});
level--;
append(_, level, "END_CONSTANTS");
}
function getLargestOPLen() {
var len = 0;
insts.instructions.forEach((a) => {
len = Math.max(len, a.name.length);
});
return len;
}
function alignInstruction(instruction) {
var buf = instruction;
2018-08-14 19:01:46 +00:00
for (var i = 0; i < getLargestOPLen() + 1 - instruction.length; i ++)
2018-08-14 12:42:05 +00:00
buf += " ";
return buf;
}
function dmpInstruction(_, level, parsedCode) {
2024-07-07 11:41:36 +00:00
if (parsedCode.instruction.type == decoder.instructionTypes.iABC)
2018-08-14 12:42:05 +00:00
append(_, level, fmt("iABC\t%s(%i, %i, %i)", alignInstruction(parsedCode.instruction.name), parsedCode.a, parsedCode.b, parsedCode.c));
2024-07-07 11:41:36 +00:00
else if (parsedCode.instruction.type == decoder.instructionTypes.iABx)
2018-08-14 12:42:05 +00:00
append(_, level, fmt("iABx\t%s(%i, %i)", alignInstruction(parsedCode.instruction.name), parsedCode.a, parsedCode.b));
2024-07-07 11:41:36 +00:00
else if (parsedCode.instruction.type == decoder.instructionTypes.iAsBx)
2018-08-14 12:42:05 +00:00
append(_, level, fmt("iAsBx\t%s(%i, %i)", alignInstruction(parsedCode.instruction.name), parsedCode.a, parsedCode.b));
}
2018-08-14 19:01:46 +00:00
function dmpCode(_, level, decoded) {
2018-08-14 12:42:05 +00:00
append(_, level, "START_CODE");
level++;
2018-08-14 19:01:46 +00:00
decoded.forEach((code) => {
2018-08-14 12:42:05 +00:00
dmpInstruction(_, level, code);
});
level--;
append(_, level, "END_CODE");
2018-08-14 19:01:46 +00:00
}
function dmpClosures(_, level, closures) {
for (var i in closures) {
var ahh = closures[i];
append(_, level, "");
append(_, level, fmt("START_CLOSURE %i", i));
level++;
dmpMethod(_, level, ahh);
level--;
append(_, level, fmt("END_CLOSURE %i", i));
}
}
function dmpDbg(_, level, dbg) {
2018-08-14 12:42:05 +00:00
append(_, level, "START_DBG");
level++;
2018-08-14 19:01:46 +00:00
append(_, level, fmt("TYPE\t%i", dbg.type));
append(_, level, fmt("DATA\t%s", JSON.stringify(dbg.data)));
2018-08-14 12:42:05 +00:00
level--;
append(_, level, "END_DBG");
2018-08-14 19:01:46 +00:00
}
function dmpMethod(_, level, method) {
append(_, level, "START_METHOD");
level++;
append(_, level, fmt("FLAGS\t%i", method.flags));
append(_, level, fmt("PARAMS\t%i", method.params));
append(_, level, fmt("UPVALS\t%i", method.upvals));
append(_, level, fmt("REGCNT\t%i", method.registers));
append(_, level, "");
dmpCode(_, level, method.decoded);
2018-08-14 12:42:05 +00:00
append(_, level, "");
dmpConstants(_, level, method.constants);
2018-08-14 19:01:46 +00:00
append(_, level, "");
dmpDbg(_, level, method.debug);
dmpClosures(_, level, method.closures);
2018-08-14 12:42:05 +00:00
level--;
append(_, level, "END_METHOD");
}
function dmpHeader(_, level, header) {
append(_, level, "START_HEADER");
level++;
append(_, level, fmt("VERSION\t%i", header.version));
append(_, level, fmt("LENDIAN\t%s", header.isLE ? "true" : "false"));
append(_, level, "START_NUMBER_SIZES");
level++;
2019-07-10 16:03:46 +00:00
append(_, level, fmt("NUMBER %i", header.numberSize));
append(_, level, fmt("INTEGER %i", header.intSize));
2018-08-14 12:42:05 +00:00
append(_, level, fmt("INSTRUCTION %i", header.instructionSize));
2019-07-10 16:03:46 +00:00
append(_, level, fmt("SIZE_T %i", header.machineSize));
2018-08-14 12:42:05 +00:00
level--;
append(_, level, "END_NUMBER_SIZES");
append(_, level, fmt("FLAGS\t%i", header.platformFlags));
append(_, level, fmt("TYPES\t%i", header.numOfTypes));
append(_, level, fmt("SHARE\t%s", header.share ? "true" : "false"));
level--;
append(_, level, "END_HEADER");
}
function dmpContext(_, context) {
append(_, 0, "START_SCRIPT");
dmpHeader(_, 1, context.header);
append(_, 0, "");
dmpMethod(_, 1, context.mainMethod);
append(_, 0, "END_SCRIPT");
}
module.exports = {
dsmContext: dmpContext
}