cache: allow passing instruction set to assembler
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class InstructionsTest
|
||||
@Test
|
||||
public void testInit()
|
||||
{
|
||||
Instructions.init();
|
||||
new Instructions().init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user