mirror of
https://github.com/Wack0/IFPSTools.NET.git
synced 2025-06-18 10:45:36 -04:00
libifps: allow Instruction.Create(OpCode, Operand, Operand, Operand) to be used for InlineCmpValueType too
libasm: allow generic operand to be used for InlineCmpValueType op2, as well as type tests: refactor and fix tests: add test for InlineCmpValueType on type and variable
This commit is contained in:
parent
8aea82c678
commit
b20d5d88b5
@ -693,11 +693,20 @@ namespace IFPSAsmLib
|
||||
var op1 = ParseOperandValue(next, function, types, globals, functions, aliases, defines);
|
||||
if (next.Next == null) next.ThrowInvalid();
|
||||
next = next.Next;
|
||||
next.ExpectValidName();
|
||||
next.EnsureNoNextChild();
|
||||
if (!types.TryGetValue(next.Value, out var typeOp)) next.ThrowInvalid(string.Format("In function \"{0}\": Referenced unknown type", function.Name));
|
||||
Operand op2 = null;
|
||||
try
|
||||
{
|
||||
op2 = ParseOperandValue(next, function, types, globals, functions, aliases, defines);
|
||||
}
|
||||
catch
|
||||
{
|
||||
next.ExpectValidName();
|
||||
next.EnsureNoNextChild();
|
||||
if (!types.TryGetValue(next.Value, out var typeOp)) next.ThrowInvalid(string.Format("In function \"{0}\": Referenced unknown type", function.Name));
|
||||
op2 = Operand.Create(typeOp);
|
||||
}
|
||||
if (next.Next != null) next.Next.ThrowInvalid();
|
||||
return Instruction.Create(opcode, op0, op1, typeOp);
|
||||
return Instruction.Create(opcode, op0, op1, op2);
|
||||
}
|
||||
case OperandType.InlineTypeVariable:
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -61,6 +61,7 @@
|
||||
<None Include="CompiledCode.bin" />
|
||||
<None Include="CompiledCode_v22.bin" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="TestIsInsn.bin" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
@ -85,6 +86,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="CompiledCode_v22.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="TestIsInsn.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
34
IFPSLib.Tests/Properties/Resources.Designer.cs
generated
34
IFPSLib.Tests/Properties/Resources.Designer.cs
generated
@ -135,5 +135,39 @@ namespace IFPSLib.Tests.Properties {
|
||||
return ResourceManager.GetString("CompiledCodeDisasm_v22", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] TestIsInsn {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("TestIsInsn", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to .version 23
|
||||
///
|
||||
///.type primitive(Pointer) Pointer
|
||||
///.type primitive(S32) S32
|
||||
///.type primitive(U32) U32
|
||||
///.type primitive(U8) U8
|
||||
///
|
||||
///.function(export) U8 INITIALIZEUNINSTALL()
|
||||
/// pushtype U32 ; StackCount = 1
|
||||
/// pushtype U32 ; StackCount = 2
|
||||
/// is Var1, Var2, S32
|
||||
/// is Var1, Var2, Var1
|
||||
/// ret
|
||||
///
|
||||
///
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string TestIsInsnDisasm {
|
||||
get {
|
||||
return ResourceManager.GetString("TestIsInsnDisasm", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,4 +130,10 @@
|
||||
<data name="CompiledCode_v22" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\CompiledCode_v22.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="TestIsInsn" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\TestIsInsn.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="TestIsInsnDisasm" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\TestIsInsn.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
</root>
|
@ -10,18 +10,16 @@ namespace IFPSLib.Tests
|
||||
[TestClass]
|
||||
public class ScriptTest
|
||||
{
|
||||
private static readonly string origB64 = Convert.ToBase64String(Resources.CompiledCode);
|
||||
private static readonly string origB64_22 = Convert.ToBase64String(Resources.CompiledCode_v22);
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSave()
|
||||
private void TestLoadSaveImpl(byte[] compiled)
|
||||
{
|
||||
// Convert to base64.
|
||||
string orig = Convert.ToBase64String(compiled);
|
||||
// Load the script.
|
||||
var script = Script.Load(Resources.CompiledCode);
|
||||
var script = Script.Load(compiled);
|
||||
// Ensure it's not null.
|
||||
Assert.IsNotNull(script);
|
||||
// For an official script (compiled by inno setup), the entrypoint is the first function.
|
||||
Assert.AreEqual(script.EntryPoint, script.Functions[0]);
|
||||
if (script.EntryPoint != null) Assert.AreEqual(script.EntryPoint, script.Functions[0]);
|
||||
// Save the script.
|
||||
var savedBytes = script.Save();
|
||||
// Convert to base64 for later.
|
||||
@ -33,50 +31,53 @@ namespace IFPSLib.Tests
|
||||
// Ensure both saved scripts equal each other.
|
||||
Assert.AreEqual(saved, savedTwice);
|
||||
// Ensure the saved script equals the original.
|
||||
Assert.AreEqual(saved, origB64);
|
||||
Assert.AreEqual(saved, orig);
|
||||
// Ensure the disassemblies are equal.
|
||||
Assert.AreEqual(script.Disassemble(), scriptSaved.Disassemble());
|
||||
}
|
||||
|
||||
private void TestAsmImpl(string disasm, byte[] compiled)
|
||||
{
|
||||
string orig = Convert.ToBase64String(compiled);
|
||||
var script = Assembler.Assemble(disasm);
|
||||
var savedB64 = Convert.ToBase64String(script.Save());
|
||||
Assert.AreEqual(savedB64, orig);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSave()
|
||||
{
|
||||
TestLoadSaveImpl(Resources.CompiledCode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAsm()
|
||||
{
|
||||
var script = Assembler.Assemble(Resources.CompiledCodeDisasm);
|
||||
var savedB64 = Convert.ToBase64String(script.Save());
|
||||
Assert.AreEqual(savedB64, origB64);
|
||||
TestAsmImpl(Resources.CompiledCodeDisasm, Resources.CompiledCode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSaveV22()
|
||||
{
|
||||
// Load the script.
|
||||
var script = Script.Load(Resources.CompiledCode_v22);
|
||||
// Ensure it's not null.
|
||||
Assert.IsNotNull(script);
|
||||
// For an official script (compiled by inno setup), the entrypoint is the first function.
|
||||
Assert.AreEqual(script.EntryPoint, script.Functions[0]);
|
||||
// Save the script.
|
||||
var savedBytes = script.Save();
|
||||
// Convert to base64 for later.
|
||||
var saved = Convert.ToBase64String(savedBytes);
|
||||
// Load the saved script.
|
||||
var scriptSaved = Script.Load(savedBytes);
|
||||
// Save again.
|
||||
var savedTwice = Convert.ToBase64String(scriptSaved.Save());
|
||||
// Ensure both saved scripts equal each other.
|
||||
Assert.AreEqual(saved, savedTwice);
|
||||
// Ensure the saved script equals the original.
|
||||
Assert.AreEqual(saved, origB64_22);
|
||||
// Ensure the disassemblies are equal.
|
||||
Assert.AreEqual(script.Disassemble(), scriptSaved.Disassemble());
|
||||
TestLoadSaveImpl(Resources.CompiledCode_v22);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAsmV22()
|
||||
{
|
||||
var script = Assembler.Assemble(Resources.CompiledCodeDisasm_v22);
|
||||
var savedB64 = Convert.ToBase64String(script.Save());
|
||||
Assert.AreEqual(savedB64, origB64);
|
||||
TestAsmImpl(Resources.CompiledCodeDisasm_v22, Resources.CompiledCode_v22);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestLoadSaveIs()
|
||||
{
|
||||
TestLoadSaveImpl(Resources.TestIsInsn);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAsmIs()
|
||||
{
|
||||
TestAsmImpl(Resources.TestIsInsnDisasm, Resources.TestIsInsn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
IFPSLib.Tests/TestIsInsn.bin
Normal file
BIN
IFPSLib.Tests/TestIsInsn.bin
Normal file
Binary file not shown.
15
IFPSLib.Tests/TestIsInsn.txt
Normal file
15
IFPSLib.Tests/TestIsInsn.txt
Normal file
@ -0,0 +1,15 @@
|
||||
.version 23
|
||||
|
||||
.type primitive(Pointer) Pointer
|
||||
.type primitive(S32) S32
|
||||
.type primitive(U32) U32
|
||||
.type primitive(U8) U8
|
||||
|
||||
.function(export) U8 INITIALIZEUNINSTALL()
|
||||
pushtype U32 ; StackCount = 1
|
||||
pushtype U32 ; StackCount = 2
|
||||
is Var1, Var2, S32
|
||||
is Var1, Var2, Var1
|
||||
ret
|
||||
|
||||
|
@ -250,7 +250,8 @@ namespace IFPSLib.Emit
|
||||
/// <returns>New instruction</returns>
|
||||
public static Instruction Create(OpCode opcode, Operand op0, Operand op1, Operand op2)
|
||||
{
|
||||
if (opcode.OperandType != OperandType.InlineCmpValue) throw new ArgumentOutOfRangeException(nameof(opcode), "Opcode does not have three value operands");
|
||||
if (opcode.OperandType != OperandType.InlineCmpValue && opcode.OperandType != OperandType.InlineCmpValueType)
|
||||
throw new ArgumentOutOfRangeException(nameof(opcode), "Opcode does not have three value operands");
|
||||
return new Instruction(opcode, new List<Operand>(3) { op0, op1, op2 });
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user