cache: allow passing instruction set to assembler

This commit is contained in:
Adam
2018-01-26 20:31:31 -05:00
parent 4624371bf9
commit e650637176
8 changed files with 39 additions and 24 deletions

View File

@@ -30,14 +30,11 @@ import static net.runelite.cache.script.Opcodes.*;
public class Instructions
{
private static final Map<Integer, Instruction> instructions = new HashMap<>();
private static final Map<String, Instruction> instructionsByName = new HashMap<>();
private final Map<Integer, Instruction> instructions = new HashMap<>();
private final Map<String, Instruction> instructionsByName = new HashMap<>();
public static void init()
public void init()
{
instructions.clear();
instructionsByName.clear();
add(LOAD_INT, "load_int", 0, 1);
add(GET_SETTINGS, "get_settings", 0, 1);
add(PUT_SETTINGS, "put_settings", 0, 1);
@@ -536,7 +533,7 @@ public class Instructions
add(6699, 0, 1);
}
private static void add(int opcode, String name, int ipops, int ipushes, int spops, int spushes)
protected void add(int opcode, String name, int ipops, int ipushes, int spops, int spushes)
{
Instruction i = new Instruction(opcode);
i.setName(name);
@@ -555,27 +552,27 @@ public class Instructions
}
}
private static void add(int opcode, int ipops, int ipushes)
protected void add(int opcode, int ipops, int ipushes)
{
add(opcode, null, ipops, ipushes, 0, 0);
}
private static void add(int opcode, int ipops, int ipushes, int spops, int spushes)
protected void add(int opcode, int ipops, int ipushes, int spops, int spushes)
{
add(opcode, null, ipops, ipushes, spops, spushes);
}
private static void add(int opcode, String name, int ipops, int ipushes)
protected void add(int opcode, String name, int ipops, int ipushes)
{
add(opcode, name, ipops, ipushes, 0, 0);
}
public static Instruction find(int opcode)
public Instruction find(int opcode)
{
return instructions.get(opcode);
}
public static Instruction find(String name)
public Instruction find(String name)
{
return instructionsByName.get(name);
}

View File

@@ -35,10 +35,15 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
public class Assembler
{
private final Instructions instructions;
public Assembler(Instructions instructions)
{
this.instructions = instructions;
}
public ScriptDefinition assemble(InputStream in) throws IOException
{
Instructions.init();
// Get our lexer
rs2asmLexer lexer = new rs2asmLexer(new ANTLRInputStream(in));
@@ -66,7 +71,7 @@ public class Assembler
LabelVisitor labelVisitor = new LabelVisitor();
walker.walk(labelVisitor, progContext);
ScriptWriter listener = new ScriptWriter(labelVisitor);
ScriptWriter listener = new ScriptWriter(instructions, labelVisitor);
walker.walk(listener, progContext);
return listener.buildScript();

View File

@@ -39,6 +39,7 @@ public class ScriptWriter extends rs2asmBaseListener
{
private static final Logger logger = LoggerFactory.getLogger(ScriptWriter.class);
private final Instructions instructions;
private final LabelVisitor labelVisitor;
private int pos;
@@ -51,8 +52,9 @@ public class ScriptWriter extends rs2asmBaseListener
private List<String> sops = new ArrayList<>();
private List<LookupSwitch> switches = new ArrayList<>();
public ScriptWriter(LabelVisitor labelVisitor)
public ScriptWriter(Instructions instructions, LabelVisitor labelVisitor)
{
this.instructions = instructions;
this.labelVisitor = labelVisitor;
}
@@ -94,7 +96,7 @@ public class ScriptWriter extends rs2asmBaseListener
public void enterName_string(rs2asmParser.Name_stringContext ctx)
{
String text = ctx.getText();
Instruction i = Instructions.find(text);
Instruction i = instructions.find(text);
if (i == null)
{
logger.warn("Unknown instruction {}", text);

View File

@@ -38,6 +38,13 @@ public class Disassembler
{
private static final Logger logger = LoggerFactory.getLogger(Disassembler.class);
private final Instructions instructions = new Instructions();
public Disassembler()
{
instructions.init();
}
private boolean isJump(int opcode)
{
switch (opcode)
@@ -120,7 +127,7 @@ public class Disassembler
int iop = iops[i];
String sop = sops[i];
Instruction ins = Instructions.find(opcode);
Instruction ins = this.instructions.find(opcode);
if (ins == null)
{
logger.warn("Unknown instruction {} in script {}", opcode, script.getId());

View File

@@ -27,6 +27,7 @@ package net.runelite.cache.definitions.savers;
import java.io.IOException;
import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.definitions.loaders.ScriptLoader;
import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.assembler.Assembler;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
@@ -42,7 +43,9 @@ public class ScriptSaverTest
@Test
public void testSave() throws IOException
{
ScriptDefinition script = new Assembler().assemble(getClass().getResourceAsStream(SCRIPT_RESOURCE));
Instructions instructions = new Instructions();
instructions.init();
ScriptDefinition script = new Assembler(instructions).assemble(getClass().getResourceAsStream(SCRIPT_RESOURCE));
byte[] saved = new ScriptSaver().save(script);
ScriptDefinition loadedScripot = new ScriptLoader().load(42, saved);
assertEquals(script, loadedScripot);

View File

@@ -31,7 +31,7 @@ public class InstructionsTest
@Test
public void testInit()
{
Instructions.init();
new Instructions().init();
}
}

View File

@@ -26,6 +26,7 @@ package net.runelite.cache.script.assembler;
import java.io.InputStream;
import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.disassembler.Disassembler;
import org.apache.commons.compress.utils.IOUtils;
import org.junit.Assert;
@@ -60,7 +61,10 @@ public class AssemblerTest
InputStream in = AssemblerTest.class.getResourceAsStream(script);
Assert.assertNotNull(in);
Assembler assembler = new Assembler();
Instructions instructions = new Instructions();
instructions.init();
Assembler assembler = new Assembler(instructions);
ScriptDefinition script = assembler.assemble(in);
// compare with disassembler

View File

@@ -35,7 +35,6 @@ import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store;
import net.runelite.cache.script.Instructions;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -55,8 +54,6 @@ public class DisassemblerTest
File outDir = folder.newFolder();
int count = 0;
Instructions.init();
try (Store store = new Store(StoreLocation.LOCATION))
{
store.load();