cache: add names to instructions

update script dumper to use names if available, and show labels/jumps
This commit is contained in:
Adam
2017-03-03 13:14:01 -05:00
parent d81630ff90
commit cc0b5e1aa7
2 changed files with 259 additions and 176 deletions

View File

@@ -24,8 +24,6 @@
*/
package net.runelite.cache;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
@@ -35,6 +33,9 @@ import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.File;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import net.runelite.cache.script.Instruction;
import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.Opcodes;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -45,8 +46,6 @@ public class ScriptDumperTest
{
private static final Logger logger = LoggerFactory.getLogger(ScriptDumperTest.class);
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
@@ -56,6 +55,8 @@ public class ScriptDumperTest
java.io.File outDir = folder.newFolder();
int count = 0;
Instructions.init();
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();
@@ -72,7 +73,7 @@ public class ScriptDumperTest
ScriptDefinition script = loader.load(file.getFileId(), contents);
java.io.File outFile = new java.io.File(outDir, archive.getArchiveId() + ".rs");
java.io.File outFile = new java.io.File(outDir, archive.getArchiveId() + ".rs2asm");
writeScript(outFile, script);
++count;
@@ -82,26 +83,92 @@ public class ScriptDumperTest
logger.info("Dumped {} scripts to {}", count, outDir);
}
private boolean[] needLabel(ScriptDefinition script)
{
int[] instructions = script.getInstructions();
int[] iop = script.getIntOperands();
boolean[] jumped = new boolean[instructions.length];
for (int i = 0; i < instructions.length; ++i)
{
int opcode = instructions[i];
if (opcode != Opcodes.JUMP)
{
continue;
}
// + 1 because the jumps go to the instructions prior to the
// one you really want, because the pc is incremented on the
// next loop
int to = i + iop[i] + 1;
assert to >= 0 && to < instructions.length;
jumped[to] = true;
}
return jumped;
}
private void writeScript(java.io.File file, ScriptDefinition script) throws IOException
{
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file)))
{
int length = script.getInstructions().length;
int[] instructions = script.getInstructions();
int[] iops = script.getIntOperands();
String[] sops = script.getStringOperands();
assert script.getIntOperands().length == length;
assert script.getStringOperands().length == length;
assert iops.length == instructions.length;
assert sops.length == instructions.length;
for (int i = 0; i < length; ++i)
boolean[] jumps = needLabel(script);
for (int i = 0; i < instructions.length; ++i)
{
int opcode = script.getInstructions()[i];
int iop = script.getIntOperands()[i];
String sop = script.getStringOperands()[i];
int opcode = instructions[i];
int iop = iops[i];
String sop = sops[i];
Instruction ins = Instructions.find(opcode);
if (ins == null)
{
logger.warn("Unknown instruction {} in script {}", opcode, script.getId());
}
String name;
if (ins != null && ins.getName() != null)
{
name = ins.getName();
}
else
{
name = String.format("%03d", opcode);
}
if (jumps[i])
{
// something jumps here
writer.write("LABEL" + i + ":\n");
}
writer.write(String.format(" %-22s", name));
if (iop != 0 || opcode == Opcodes.LOAD_INT)
{
if (opcode == Opcodes.JUMP)
{
writer.write(" LABEL" + (i + iop));
}
else
{
writer.write(" " + iop);
}
}
writer.write(String.format("0x%03x", opcode));
if (iop != 0 || sop != null)
writer.write(" " + iop);
if (sop != null)
writer.write(" " + sop);
{
writer.write(" \"" + sop + "\"");
}
writer.write("\n");
}
}