private PapyrusInstruction ReadInstruction(PapyrusAssemblyDefinition asm) { var instruction = new PapyrusInstruction(); instruction.OpCode = (PapyrusOpCodes)pexReader.ReadByte(); var desc = PapyrusInstructionOpCodeDescription.FromOpCode(instruction.OpCode); var references = new List <PapyrusVariableReference>(); var instructionParamSize = desc.ArgumentCount; for (var p = 0; p < instructionParamSize; p++) { references.Add(ReadValueReference(asm)); } if (desc.HasOperandArguments) { var typeRef = ReadValueReference(asm); if (typeRef.Type == PapyrusPrimitiveType.Integer) { var argCount = (int)typeRef.Value; for (var i = 0; i < argCount; i++) { instruction.OperandArguments.Add(ReadValueReference(asm)); } } } instruction.Arguments = references; return(instruction); }
public void PapyrusParser_GetOpCodeFromAlias() { var desc = PapyrusInstructionOpCodeDescription.FromAlias("CALLMETHOD"); Assert.IsNotNull(desc); Assert.AreEqual(PapyrusOpCodes.Callmethod, desc.Key); }
private static InstructionArgumentEditorViewModel CreateViewModel() { var reader = new OpCodeDescriptionReader(); IOpCodeDescriptionDefinition data = null; if (File.Exists("OpCodeDescriptions.xml")) { data = reader.Read("OpCodeDescriptions.xml"); } else if (File.Exists(@"C:\git\PapyrusDotNet\Source\PapyrusDotNet.PexInspector\OpCodeDescriptions.xml")) { data = reader.Read(@"C:\git\PapyrusDotNet\Source\PapyrusDotNet.PexInspector\OpCodeDescriptions.xml"); } else { data = reader.Read(@"D:\git\PapyrusDotNet\Source\PapyrusDotNet.PexInspector\OpCodeDescriptions.xml"); } var desc = data.GetDesc(PapyrusOpCodes.Cast); if (desc.Arguments == null || desc.Arguments.Count == 0) { desc.Arguments = new List <OpCodeArgumentDescription>(); var fallbackDesc = PapyrusInstructionOpCodeDescription.FromOpCode(desc.OpCode); for (var i = 0; i < fallbackDesc.ArgumentCount; i++) { desc.Arguments.Add(new OpCodeArgumentDescription { Index = i, Alias = "Value" + (i + 1), Ref = OpCodeRef.None, Description = "", ValueType = OpCodeValueTypes.ReferenceOrConstant }); } } return(new InstructionArgumentEditorViewModel(null, null, null, null, null, null, desc)); }
private void WriteInstruction(PapyrusInstruction instruction) { pexWriter.Write((byte)instruction.OpCode); var desc = PapyrusInstructionOpCodeDescription.FromOpCode(instruction.OpCode); foreach (var arg in instruction.Arguments) { WriteValueReference(arg); } if (desc.HasOperandArguments) { WriteValueReference(new PapyrusVariableReference { Value = instruction.OperandArguments.Count, Type = PapyrusPrimitiveType.Integer }); foreach (var varg in instruction.OperandArguments) { WriteValueReference(varg); } } }
/// <summary> /// Parses the string represented instruction and returns a <see cref="PapyrusAsmInstruction"/>. /// </summary> /// <param name="instruction">The instruction.</param> /// <returns></returns> public PapyrusAsmInstruction ParseInstruction(string instruction) { if (string.IsNullOrEmpty(instruction)) { return(null); } var data = GetAsmValues(instruction.Trim().Trim(' ', '\t')); var desc = PapyrusInstructionOpCodeDescription.FromAlias(data[0].Value); var ins = new PapyrusAsmInstruction(desc.Key, desc.Value.ArgumentCount, desc.Value.HasOperandArguments, desc.Value.Aliases); for (var i = 0; i < ins.ArgumentCount; i++) { ins.SetArgument(i, data[i + 1]); } var opargs = data.Count - ins.ArgumentCount - 1; for (var i = 0; i < opargs; i++) { ins.SetOperandArgument(i, data[i + ins.ArgumentCount + 1]); } return(ins); }
/// <summary> /// Gets the size of the instruction parameter. /// </summary> /// <param name="opcode">The opcode.</param> /// <returns></returns> public static int GetInstructionParamSize(this PapyrusOpCodes opcode) { return(PapyrusInstructionOpCodeDescription.FromOpCode(opcode).ArgumentCount); }