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 public class Instructions
{ {
private static final Map<Integer, Instruction> instructions = new HashMap<>(); private final Map<Integer, Instruction> instructions = new HashMap<>();
private static final Map<String, Instruction> instructionsByName = 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(LOAD_INT, "load_int", 0, 1);
add(GET_SETTINGS, "get_settings", 0, 1); add(GET_SETTINGS, "get_settings", 0, 1);
add(PUT_SETTINGS, "put_settings", 0, 1); add(PUT_SETTINGS, "put_settings", 0, 1);
@@ -536,7 +533,7 @@ public class Instructions
add(6699, 0, 1); 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); Instruction i = new Instruction(opcode);
i.setName(name); 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); 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); 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); add(opcode, name, ipops, ipushes, 0, 0);
} }
public static Instruction find(int opcode) public Instruction find(int opcode)
{ {
return instructions.get(opcode); return instructions.get(opcode);
} }
public static Instruction find(String name) public Instruction find(String name)
{ {
return instructionsByName.get(name); return instructionsByName.get(name);
} }

View File

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

View File

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

View File

@@ -38,6 +38,13 @@ public class Disassembler
{ {
private static final Logger logger = LoggerFactory.getLogger(Disassembler.class); private static final Logger logger = LoggerFactory.getLogger(Disassembler.class);
private final Instructions instructions = new Instructions();
public Disassembler()
{
instructions.init();
}
private boolean isJump(int opcode) private boolean isJump(int opcode)
{ {
switch (opcode) switch (opcode)
@@ -120,7 +127,7 @@ public class Disassembler
int iop = iops[i]; int iop = iops[i];
String sop = sops[i]; String sop = sops[i];
Instruction ins = Instructions.find(opcode); Instruction ins = this.instructions.find(opcode);
if (ins == null) if (ins == null)
{ {
logger.warn("Unknown instruction {} in script {}", opcode, script.getId()); 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 java.io.IOException;
import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.definitions.loaders.ScriptLoader; import net.runelite.cache.definitions.loaders.ScriptLoader;
import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.assembler.Assembler; import net.runelite.cache.script.assembler.Assembler;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Test; import org.junit.Test;
@@ -42,7 +43,9 @@ public class ScriptSaverTest
@Test @Test
public void testSave() throws IOException 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); byte[] saved = new ScriptSaver().save(script);
ScriptDefinition loadedScripot = new ScriptLoader().load(42, saved); ScriptDefinition loadedScripot = new ScriptLoader().load(42, saved);
assertEquals(script, loadedScripot); assertEquals(script, loadedScripot);

View File

@@ -31,7 +31,7 @@ public class InstructionsTest
@Test @Test
public void testInit() 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 java.io.InputStream;
import net.runelite.cache.definitions.ScriptDefinition; import net.runelite.cache.definitions.ScriptDefinition;
import net.runelite.cache.script.Instructions;
import net.runelite.cache.script.disassembler.Disassembler; import net.runelite.cache.script.disassembler.Disassembler;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.compress.utils.IOUtils;
import org.junit.Assert; import org.junit.Assert;
@@ -60,7 +61,10 @@ public class AssemblerTest
InputStream in = AssemblerTest.class.getResourceAsStream(script); InputStream in = AssemblerTest.class.getResourceAsStream(script);
Assert.assertNotNull(in); Assert.assertNotNull(in);
Assembler assembler = new Assembler(); Instructions instructions = new Instructions();
instructions.init();
Assembler assembler = new Assembler(instructions);
ScriptDefinition script = assembler.assemble(in); ScriptDefinition script = assembler.assemble(in);
// compare with disassembler // 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.Index;
import net.runelite.cache.fs.Storage; import net.runelite.cache.fs.Storage;
import net.runelite.cache.fs.Store; import net.runelite.cache.fs.Store;
import net.runelite.cache.script.Instructions;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
@@ -55,8 +54,6 @@ public class DisassemblerTest
File outDir = folder.newFolder(); File outDir = folder.newFolder();
int count = 0; int count = 0;
Instructions.init();
try (Store store = new Store(StoreLocation.LOCATION)) try (Store store = new Store(StoreLocation.LOCATION))
{ {
store.load(); store.load();