mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-22 09:37:17 +00:00
136 lines
3.1 KiB
JavaScript
136 lines
3.1 KiB
JavaScript
const { COMMANDS } = require("./constants");
|
|
|
|
class Variable {
|
|
constructor(a, b, name) {
|
|
this.a = a;
|
|
this.b = b;
|
|
this.name = name;
|
|
}
|
|
}
|
|
|
|
function decodeUInt32(code) {
|
|
// prettier-ignore
|
|
return (
|
|
(code.charCodeAt(3) << 24) +
|
|
(code.charCodeAt(2) << 16) +
|
|
(code.charCodeAt(1) << 8) +
|
|
code.charCodeAt(0)
|
|
);
|
|
}
|
|
|
|
function decodeInt32(code) {
|
|
let num = decodeUInt32(code);
|
|
if (num > 0x7fffffff) {
|
|
num = num - 0xffffffff - 1;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
class Command {
|
|
constructor({
|
|
functionsCode,
|
|
pos,
|
|
types,
|
|
variables,
|
|
functionNames,
|
|
localFunctions
|
|
}) {
|
|
const opcode = functionsCode.charCodeAt(pos);
|
|
this.pos = pos;
|
|
this.opcode = opcode;
|
|
this.arguments = [];
|
|
this.command = COMMANDS[opcode];
|
|
|
|
if (this.command == null) {
|
|
this.command = {
|
|
name: `unknown ${opcode}`,
|
|
in: 0,
|
|
out: 0
|
|
};
|
|
return;
|
|
}
|
|
|
|
if (this.command.arg == null) {
|
|
this.size = 1;
|
|
return;
|
|
}
|
|
|
|
const argType = this.command.arg;
|
|
let arg = null;
|
|
switch (argType) {
|
|
case "var": {
|
|
const variable = decodeInt32(functionsCode.substr(pos + 1, 4));
|
|
if (variables[variable] != null) {
|
|
arg = variables[variable];
|
|
} else {
|
|
arg = new Variable(-1, -0, "unknown");
|
|
}
|
|
this.name = `Unknown ${variable}`;
|
|
break;
|
|
}
|
|
case "line": {
|
|
const variable = decodeInt32(functionsCode.substr(pos + 1, 4)) + 5;
|
|
arg = { name: variable, line: variable };
|
|
break;
|
|
}
|
|
case "objFunc": {
|
|
const variable = decodeInt32(functionsCode.substr(pos + 1, 4));
|
|
if (functionNames[variable] != null) {
|
|
arg = functionNames[variable].function;
|
|
} else {
|
|
arg = {
|
|
name: `unknown Object function ${variable}`,
|
|
parameters: [],
|
|
return: "unknown"
|
|
};
|
|
}
|
|
break;
|
|
}
|
|
case "func": {
|
|
// Note in the perl code here: "todo, something strange going on here..."
|
|
const variable = decodeInt32(functionsCode.substr(pos + 1, 4)) + 5;
|
|
const s = functionsCode.substr(pos + 1, 1);
|
|
console.log(functionsCode.length);
|
|
console.log(s.charCodeAt(0));
|
|
arg = {
|
|
name: `func${variable + pos}`,
|
|
code: [],
|
|
offset: variable + pos
|
|
};
|
|
if (opcode === 25) {
|
|
// console.log(variable);
|
|
}
|
|
if (localFunctions[variable + pos] == null) {
|
|
localFunctions[variable + pos] = {
|
|
function: arg,
|
|
offset: variable + pos
|
|
};
|
|
}
|
|
break;
|
|
}
|
|
case "obj": {
|
|
const variable = decodeInt32(functionsCode.substr(pos + 1, 4));
|
|
arg = types[variable];
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.arguments = [arg];
|
|
this.size = 5;
|
|
|
|
/*
|
|
# look forward for a stack protection block
|
|
# (why do I have to look FORWARD. stupid nullsoft)
|
|
if( length($code) > $pos+5+4 &&
|
|
decodeUInt32( substr( $code, $pos+5, 4 ) ) >= 0xffff0000 ) {
|
|
$self->{size} += 4;
|
|
}
|
|
*/
|
|
|
|
if (opcode === 112) {
|
|
this.size += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Command;
|