internal static void Main(string[] args) { if (args.Length < 1) { Console.Error.WriteLine("COULD NOT COMPILE: no path provided"); return; } // If /s option is provided, put code out as C# string if (args.Length > 1 && args[1] == "/s") { ProgramBuilder builder = new ProgramBuilder(args[0]); builder.BuildProgram(); Console.Write(builder.ProgramText); return; } // Otherwise, compile the program string errors = ""; bool succeeded = Compile(args[0], ref errors); if (succeeded) { Console.WriteLine("Complete"); } else { Console.Error.WriteLine("Could not compile.\nERRORS:\n\n"); Console.Error.WriteLine(errors); } }
public static bool Compile(string path, ref string errors) { ProgramBuilder builder = new ProgramBuilder(path); builder.BuildProgram(); CSharpCodeProvider csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }); CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, builder.ProgramName + ".exe", true); parameters.GenerateExecutable = true; parameters.ReferencedAssemblies.Add("Rottytooth.Esolang.Folders.Runtime.dll"); string entireProgram = @"using System; using System.IO; using Rottytooth.Esolang.Folders.Runtime; public static class Program { private static VarManager _varManager; static Program() { _varManager = new VarManager(""" + builder.ProgramName + @"""); } " + builder.Declarations + @" public static void Main(string[] args) { " + builder.ProgramText + @" } }"; CompilerResults results = csc.CompileAssemblyFromSource(parameters, entireProgram); // output any errors StringBuilder errorList = new StringBuilder(); results.Errors.Cast<CompilerError>().ToList().ForEach(error => errorList.AppendLine(error.ErrorText)); if (errorList.Length > 0) { errors = errorList.ToString(); return false; } // we have successfully compiled return true; }
private void RunTest(ProgramBuilder p, string output) { SaveRunOutput(p.BuildProgram(), RunTest, output); }
private void GivenProgram(ProgramBuilder pb) { }
public void Setup() { arch = new X86ArchitectureFlat32("x86-protected-32"); p = new ProgramBuilder(); p.Program.Architecture = arch; }
public void Uvr_Signature() { var arch = new FakeArchitecture(); var pb = new ProgramBuilder(arch); var _r1 = arch.GetRegister("r1"); var _r2 = arch.GetRegister("r2"); pb.Add("main", m => { var r1 = m.Frame.EnsureRegister(_r1); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Call("foo", 0); m.MStore(m.Word32(0x123420), r1); }); pb.Add("foo", m => { var r1 = m.Frame.EnsureRegister(_r1); var r2 = m.Frame.EnsureRegister(_r2); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Assign(r1, m.Mem32(m.Word32(0x123400))); m.MStore(m.Word32(0x123408), r1); m.Assign(r2, m.Mem32(m.Word32(0x123410))); m.MStore(m.Word32(0x123418), r2); m.Return(); m.Procedure.Signature = FunctionType.Func( new Identifier(null, PrimitiveType.Word32, _r1), new Identifier("arg1", PrimitiveType.Word32, _r2)); }); pb.BuildProgram(); var sExp = #region Expected @"// main // Return size: 0 define main main_entry: def r2 // succ: l1 l1: r1_4 = foo(r2) Mem5[0x00123420:word32] = r1_4 main_exit: === // foo // Return size: 0 word32 foo(word32 arg1) foo_entry: def fp def Mem0 // succ: l1 l1: r63_2 = fp r1_4 = Mem0[0x00123400:word32] Mem5[0x00123408:word32] = r1_4 r2_6 = Mem5[0x00123410:word32] Mem7[0x00123418:word32] = r2_6 return // succ: foo_exit foo_exit: use r1_4 === "; #endregion RunTest(sExp, pb.Program); }
public StatementCollection(AbstractSyntaxNode node, ProgramBuilder context) : base(node, context) { }
public void Setup() { this.pb = new ProgramBuilder(); }
public void CrwFpuMultiplyAdd() { var dt = PrimitiveType.Real64; var arch = new FakeArchitecture(); var ST = arch.FpuStackBase; var _top = arch.FpuStackRegister; var pb = new ProgramBuilder(arch); pb.Add("main", m => { var Top = m.Frame.EnsureRegister(arch.FpuStackRegister); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Assign(Top, 0); m.Assign(Top, m.ISub(Top, 1)); m.MStore(ST, Top, Constant.Real64(3.0)); m.Assign(Top, m.ISub(Top, 1)); m.MStore(ST, Top, Constant.Real64(4.0)); m.Assign(Top, m.ISub(Top, 1)); m.MStore(ST, Top, Constant.Real64(5.0)); // At this point there are 3 values on the FPU stack m.Call("FpuMultiplyAdd", 0); m.MStore(m.Word32(0x00123400), m.Mem(ST, dt, Top)); m.Assign(Top, m.IAdd(Top, 1)); m.Return(); }); pb.Add("FpuMultiplyAdd", m => { var Top = m.Frame.EnsureRegister(_top); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Assign(Top, 0); m.MStore(ST, m.IAdd(Top, 1), m.FMul( m.Mem(ST, dt, m.IAdd(Top, 1)), m.Mem(ST, dt, Top))); m.Assign(Top, m.IAdd(Top, 1)); m.MStore(ST, m.IAdd(Top, 1), m.FAdd( m.Mem(ST, dt, m.IAdd(Top, 1)), m.Mem(ST, dt, Top))); m.Assign(Top, m.IAdd(Top, 1)); // At this point two values have been popped from the // FPU stack, leaving one. m.Return(); }); var sExp = #region Expected @"void main() // MayUse: // LiveOut: // Trashed: FPU -1 FPU -2 FPU -3 Top // Preserved: r63 // main // Return size: 0 // Mem0:Mem // fp:fp // Top:Top // r63:r63 // rRet0:rRet0 // rLoc1:FPU -1 // rLoc2:FPU -2 // rLoc3:FPU -3 // return address size: 0 void main() main_entry: // succ: l1 l1: rRet0_10 = FpuMultiplyAdd(5.0, 4.0, 3.0) Mem13[0x00123400:real64] = rRet0_10 return // succ: main_exit main_exit: FpuStack real64 FpuMultiplyAdd(FpuStack real64 rArg0, FpuStack real64 rArg1, FpuStack real64 rArg2) // MayUse: FPU +0:[0..63] FPU +1:[0..63] FPU +2:[0..63] // LiveOut: FPU +2 // Trashed: FPU +1 FPU +2 Top // Preserved: r63 // FpuMultiplyAdd // Return size: 0 // Mem0:Mem // fp:fp // Top:Top // r63:r63 // rArg1:FPU +1 // rArg0:FPU +0 // rArg2:FPU +2 // return address size: 0 real64 FpuMultiplyAdd(real64 rArg0, real64 rArg1, real64 rArg2) FpuMultiplyAdd_entry: def rArg1 def rArg0 def rArg2 // succ: l1 l1: rArg1_11 = rArg1 * rArg0 rArg2_13 = rArg2 + rArg1_11 return rArg2_13 // succ: FpuMultiplyAdd_exit FpuMultiplyAdd_exit: "; #endregion RunStringTest(sExp, pb.BuildProgram()); }
public static Program Generate() { var pb = new ProgramBuilder(); pb.Add("main", m => { var esp = m.Frame.EnsureRegister(m.Architecture.StackRegister); m.Assign(esp, m.Frame.FramePointer); m.Assign(esp, m.ISub(esp, 40)); m.Assign(esp, m.ISubS(esp, 4)); m.MStore(esp, m.IAdd(esp, 4)); m.Assign(esp, m.ISubS(esp, 4)); m.MStore(esp, m.Word32(10)); m.Call("twoFib", 4); m.Assign(esp, m.IAdd(esp, 52)); m.Return(); }); /// The function "twoFib" is not only recursive, but fetches data from hte caller's stack frame! pb.Add("twoFib", m => { var esp = m.Frame.EnsureRegister(m.Architecture.StackRegister); var eax = m.Reg32("eax"); var ecx = m.Reg32("ecx"); var edx = m.Reg32("edx"); var ebp = m.Reg32("ebp"); var Z = m.Frame.EnsureFlagGroup(m.Architecture.GetFlagGroup("Z")); m.Assign(esp, m.ISubS(esp, 4)); m.MStore(esp, ebp); m.Assign(ebp, esp); m.Assign(esp, m.ISub(esp, 10)); m.Assign(Z, m.Cond(m.ISub(m.Mem32(m.IAdd(ebp, 0x0C)), 0))); m.BranchIf(m.Test(ConditionCode.NE, Z), "l080483B8"); m.Label("l080483A8"); m.MStore(m.ISub(ebp, 0x08), m.Word32(0)); m.MStore(m.ISub(ebp, 0x04), m.Word32(1)); m.Goto("l080483E0"); m.Label("l080483B8"); m.Assign(edx, m.ISub(ebp, 0x08)); m.Assign(esp, m.ISub(esp, 08)); m.Assign(eax, m.Mem32(m.IAdd(ebp, 0x0C))); m.Assign(eax, m.ISub(eax, 1)); m.Assign(esp, m.ISubS(esp, 4)); m.MStore(esp, eax); m.Assign(esp, m.ISubS(esp, 4)); m.MStore(esp, edx); m.Call("twoFib", 4); m.Assign(esp, m.IAdd(esp, 0x0C)); m.Assign(eax, m.Mem32(m.ISub(ebp, 0x08))); m.MStore(m.ISub(ebp, 0x0C), eax); m.Assign(eax, m.Mem32(m.ISub(ebp, 0x04))); m.MStore(m.ISub(ebp, 0x08), eax); m.Assign(edx, m.Mem32(m.ISub(ebp, 0x0C))); m.Assign(eax, m.ISub(ebp, 0x04)); m.MStore(eax, m.IAdd(m.Mem32(eax), edx)); m.Label("l080483E0"); m.Assign(eax, m.Mem32(m.ISub(ebp, 0x08))); m.Assign(edx, m.Mem32(m.ISub(ebp, 0x04))); m.Assign(ecx, m.Mem32(m.IAdd(ebp, 0x08))); m.MStore(ecx, eax); m.MStore(m.IAdd(ecx, 0x04), edx); m.Assign(eax, m.Mem32(m.IAdd(ebp, 0x08))); m.Assign(esp, ebp); m.Assign(ebp, m.Mem32(esp)); m.Assign(esp, m.IAdd(esp, 4)); m.Return(); }); return(pb.BuildProgram()); }
public void Setup() { this.pf = new ProgramDataFlow(); this.progBuilder = new ProgramBuilder(); this.segmentMap = new SegmentMap(Address.Ptr32(0)); }
public override void Execute(SharedObjects shared) { object volumeId = shared.Cpu.PopValue(true); string fileName = shared.Cpu.PopValue(true).ToString(); if (shared.VolumeMgr == null) { return; } if (shared.VolumeMgr.CurrentVolume == null) { throw new Exception("Volume not found"); } ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName, true); if (file == null) { throw new Exception(string.Format("File '{0}' not found", fileName)); } if (shared.ScriptHandler == null) { return; } if (volumeId != null) { Volume targetVolume = shared.VolumeMgr.GetVolume(volumeId); if (targetVolume != null) { if (shared.ProcessorMgr != null) { string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName); List <CodePart> parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent); var builder = new ProgramBuilder(); builder.AddRange(parts); List <Opcode> program = builder.BuildProgram(); shared.ProcessorMgr.RunProgramOn(program, targetVolume); } } else { throw new KOSFileException("Volume not found"); } } else { // clear the "program" compilation context shared.ScriptHandler.ClearContext("program"); string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName; var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true }; var programContext = ((CPU)shared.Cpu).GetProgramContext(); List <CodePart> codeParts; if (file.Category == FileCategory.KSM) { string prefix = programContext.Program.Count.ToString(); codeParts = shared.VolumeMgr.CurrentVolume.LoadObjectFile(filePath, prefix, file.BinaryContent); } else { codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); } programContext.AddParts(codeParts); } }
public void Setup() { store = new TypeStore(); factory = new TypeFactory(); pb = new ProgramBuilder(); }
public void Dfa2_StackArgs_Nested() { pb = new ProgramBuilder(); pb.Add("main", m => { var r1 = m.Register("r1"); var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister); m.Assign(sp, m.Frame.FramePointer); m.Assign(sp, m.ISub(sp, 4)); m.MStore(sp, m.Mem32(m.Ptr32(0x123400))); m.Call("level1", 4); m.Assign(sp, m.IAdd(sp, 4)); m.MStore(m.Ptr32(0x123404), r1); m.Return(); }); pb.Add("level1", m => { var r1 = m.Register("r1"); var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister); m.Assign(sp, m.Frame.FramePointer); m.Assign(r1, m.Mem32(m.IAdd(sp, 4))); m.Assign(sp, m.ISub(sp, 4)); m.MStore(sp, r1); m.Call("level2", 4); m.Assign(sp, m.IAdd(sp, 4)); m.Return(); }); pb.Add("level2", m => { var r1 = m.Register("r1"); var r2 = m.Register("r2"); var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister); m.Assign(sp, m.Frame.FramePointer); m.Assign(r1, m.Mem32(m.IAdd(sp, 4))); m.Assign(r1, m.IAdd(r1, 1)); m.Return(); }); var program = pb.BuildProgram(); var dfa = new DataFlowAnalysis(program, dynamicLinker.Object, new FakeDecompilerEventListener()); dfa.AnalyzeProgram(); var sExp = #region Expected @"// main // Return size: 0 void main() main_entry: // succ: l1 l1: Mem8[0x00123404<p32>:word32] = level1(Mem0[0x00123400<p32>:word32]) return // succ: main_exit main_exit: === // level1 // Return size: 0 word32 level1(word32 dwArg04) level1_entry: // succ: l1 l1: return level2(dwArg04) // succ: level1_exit level1_exit: === // level2 // Return size: 0 word32 level2(word32 dwArg04) level2_entry: // succ: l1 l1: return dwArg04 + 1<32> // succ: level2_exit level2_exit: "; #endregion AssertProgram(sExp, pb.Program); }
private void Given_Architecture(IProcessorArchitecture arch) { this.arch = arch; this.builder = new ProgramBuilder(arch); }
public override void Execute(SharedObjects shared) { // run() is strange. It needs two levels of args - the args to itself, and the args it is meant to // pass on to the program it's invoking. First, these are the args to run itself: object volumeId = PopValueAssert(shared, true); string fileName = PopValueAssert(shared, true).ToString(); AssertArgBottomAndConsume(shared); // Now the args it is going to be passing on to the program: var progArgs = new List <Object>(); int argc = CountRemainingArgs(shared); for (int i = 0; i < argc; ++i) { progArgs.Add(PopValueAssert(shared, true)); } AssertArgBottomAndConsume(shared); if (shared.VolumeMgr == null) { return; } if (shared.VolumeMgr.CurrentVolume == null) { throw new Exception("Volume not found"); } ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName, true); if (file == null) { throw new Exception(string.Format("File '{0}' not found", fileName)); } if (shared.ScriptHandler == null) { return; } if (volumeId != null) { Volume targetVolume = shared.VolumeMgr.GetVolume(volumeId); if (targetVolume != null) { if (shared.ProcessorMgr != null) { string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName); var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; List <CodePart> parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); var builder = new ProgramBuilder(); builder.AddRange(parts); List <Opcode> program = builder.BuildProgram(); shared.ProcessorMgr.RunProgramOn(program, targetVolume); } } else { throw new KOSFileException("Volume not found"); } } else { // clear the "program" compilation context shared.ScriptHandler.ClearContext("program"); string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName; var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); List <CodePart> codeParts; if (file.Category == FileCategory.KSM) { string prefix = programContext.Program.Count.ToString(); codeParts = shared.VolumeMgr.CurrentVolume.LoadObjectFile(filePath, prefix, file.BinaryContent); } else { try { codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); } catch (Exception) { // If it died due to a compile error, then we won't really be able to switch to program context // as was implied by calling Cpu.SwitchToProgramContext() up above. The CPU needs to be // told that it's still in interpreter context, or else it fails to advance the interpreter's // instruction pointer and it will just try the "call run()" instruction again: shared.Cpu.BreakExecution(false); throw; } } programContext.AddParts(codeParts); } // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up, // it needs to put the return stack in a weird order. Its return value needs to be buried UNDER the args to the // program it's calling: UsesAutoReturn = false; shared.Cpu.PushStack(0); // dummy return that all functions have. // Put the args for the program being called back on in the same order they were in before (so read the list backward): shared.Cpu.PushStack(new KOSArgMarkerType()); for (int i = argc - 1; i >= 0; --i) { shared.Cpu.PushStack(progArgs[i]); } }
public void CrwOutParameter() { var pb = new ProgramBuilder(); pb.Add("main", m => { var r1 = m.Reg32("r1"); var r2 = m.Reg32("r2"); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Call("fnOutParam", 0); m.MStore(m.Word32(0x00123400), r1); m.MStore(m.Word32(0x00123404), r2); m.Return(); }); pb.Add("fnOutParam", m => { var r1 = m.Reg32("r1"); var r2 = m.Reg32("r2"); m.Label("m0"); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.BranchIf(m.Eq0(r1), "m2"); m.Label("m1"); m.Assign(r1, m.IAdd(r1, 3)); m.Assign(r2, m.ISub(r2, 3)); m.Return(); m.Label("m2"); m.Assign(r1, 0); m.Assign(r2, 0); m.Return(); }); var sExp = #region Expected @"void main(Register word32 r1, Register word32 r2) // MayUse: r1:[0..31] r2:[0..31] // LiveOut: // Trashed: r1 r2 // Preserved: r63 // main // Return size: 0 // Mem0:Mem // fp:fp // r1:r1 // r2:r2 // r63:r63 // return address size: 0 void main(word32 r1, word32 r2) main_entry: def r1 def r2 // succ: l1 l1: r1_5 = fnOutParam(r1, r2, out r2_6) Mem7[0x00123400:word32] = r1_5 Mem8[0x00123404:word32] = r2_6 return // succ: main_exit main_exit: Register word32 fnOutParam(Register word32 r1, Register word32 r2, Register out ptr32 r2Out) // MayUse: r1:[0..31] r2:[0..31] // LiveOut: r1 r2 // Trashed: r1 r2 // Preserved: r63 // fnOutParam // Return size: 0 // Mem0:Mem // fp:fp // r1:r1 // r2:r2 // r63:r63 // r2Out:Out:r2 // return address size: 0 word32 fnOutParam(word32 r1, word32 r2, ptr32 & r2Out) fnOutParam_entry: def r1 def r2 // succ: m0 m0: branch r1 == 0x00000000 m2 // succ: m1 m2 m1: r1_6 = r1 + 0x00000003 r2_8 = r2 - 0x00000003 r2Out = r2_8 return r1_6 // succ: fnOutParam_exit m2: r1_4 = 0x00000000 r2_5 = 0x00000000 r2Out = r2_5 return r1_4 // succ: fnOutParam_exit fnOutParam_exit: "; #endregion RunStringTest(sExp, pb.BuildProgram()); }
public void Setup() { this.pf = new ProgramDataFlow(); this.progBuilder = new ProgramBuilder(); }
public void Regp_Phi_Branches() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m => { var r1 = m.Register(1); var r2 = m.Register(2); m.Assign(r2, r1); m.BranchIf(m.Ge(r1, 0), "m_ge"); m.Label("m_lt"); m.Assign(r1, r2); m.Goto("m_done"); m.Label("m_ge"); m.Assign(r1, r2); m.Label("m_done"); m.Return(); }); program = pb.BuildProgram(); RunTest(program.Procedures.Values); var sExp = #region Expected @"// test // Return size: 0 void test() test_entry: def r1 // succ: l1 l1: r2_1 = r1 branch r1 >= 0x00000000 m_ge goto m_lt // succ: m_lt m_ge m_done: r1_2 = PHI(r1_3, r1_4) return // succ: test_exit m_ge: r1_4 = r2_1 goto m_done // succ: m_done m_lt: r1_3 = r2_1 goto m_done // succ: m_done test_exit: use r1_2 use r2_1 test: Preserved: r1 Trashed: r2 "; #endregion AssertProgram(sExp, program.Procedures.Values); }
public void Uvr_Forks() { var arch = new FakeArchitecture(); var pb = new ProgramBuilder(arch); var _r1 = arch.GetRegister("r1"); var _r2 = arch.GetRegister("r2"); pb.Add("main", m => { var r1 = m.Frame.EnsureRegister(_r1); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Call("foo", 0); m.MStore(m.Word32(0x123420), r1); }); pb.Add("foo", m => { var r1 = m.Frame.EnsureRegister(_r1); var r2 = m.Frame.EnsureRegister(_r2); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Assign(r1, m.Mem32(m.Word32(0x123400))); m.MStore(m.Word32(0x123408), r1); m.Assign(r2, m.Mem32(m.Word32(0x123410))); m.MStore(m.Word32(0x123418), r2); m.Return(); }); pb.BuildProgram(); var sExp = #region Expected @"// main // Return size: 0 define main main_entry: // succ: l1 l1: call foo (retsize: 0;) defs: r1:r1_3 Mem5[0x00123420:word32] = r1_3 main_exit: === // foo // Return size: 0 define foo foo_entry: def Mem0 // succ: l1 l1: r1_4 = Mem0[0x00123400:word32] Mem5[0x00123408:word32] = r1_4 r2_6 = Mem5[0x00123410:word32] Mem7[0x00123418:word32] = r2_6 return // succ: foo_exit foo_exit: use r1_4 === "; #endregion RunTest(sExp, pb.Program); }
public void Regp_WhileDo() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m => { var r1 = m.Register(1); var r2 = m.Register(2); var r3 = m.Register(3); m.Assign(r2, r1); m.Assign(r3, r2); m.Assign(r1, 10); m.Goto("m_loopHead"); m.Label("m_loopStatements"); m.Assign(r1, m.ISub(r1, 1)); m.Assign(r2, r3); m.Label("m_loopHead"); m.BranchIf(m.Ge(r1, 0), "m_loopStatements"); m.Label("m_xit"); m.Assign(r1, r2); m.Return(); }); program = pb.BuildProgram(); RunTest(program.Procedures.Values); var sExp = #region Expected @"// test // Return size: 0 void test() test_entry: def r1 // succ: l1 l1: r2_1 = r1 r3_2 = r2_1 r1_3 = 0x0000000A // succ: m_loopHead m_loopHead: r2_4 = PHI(r2_1, r2_8) r1_5 = PHI(r1_3, r1_7) branch r1_5 >= 0x00000000 m_loopStatements goto m_xit // succ: m_xit m_loopStatements m_loopStatements: r1_7 = r1_5 - 0x00000001 r2_8 = r3_2 goto m_loopHead // succ: m_loopHead m_xit: r1_6 = r2_4 return // succ: test_exit test_exit: use r1_6 use r2_4 use r3_2 test: Preserved: r1 Trashed: r2 r3 "; #endregion AssertProgram(sExp, program.Procedures.Values); }
public void Uvr_Chain() { var arch = new FakeArchitecture(); var _r1 = arch.GetRegister("r1"); var _r2 = arch.GetRegister("r2"); var _r3 = arch.GetRegister("r3"); var pb = new ProgramBuilder(); pb.Add("main", m => { var r1 = m.Frame.EnsureRegister(_r1); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Call("level1", 0); m.MStore(m.Word32(0x00123400), m.Cast(PrimitiveType.Byte, r1)); // forces r1 to be liveout on level1 m.Return(); }); pb.Add("level1", m => { // We expect r2 to be live-in, as level2 uses it, and r1 to be leve m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Call("level2", 0); m.Return(); }); pb.Add("level2", m => { var r1 = m.Frame.EnsureRegister(_r1); var r2 = m.Frame.EnsureRegister(_r2); m.Assign(m.Frame.EnsureRegister(m.Architecture.StackRegister), m.Frame.FramePointer); m.Assign(r1, m.Mem32(r2)); m.Return(); }); pb.BuildProgram(); var sExp = #region @"// main // Return size: 0 define main main_entry: def r2 // succ: l1 l1: call level1 (retsize: 0;) uses: r2:r2 defs: r1:r1_4 Mem5[0x00123400:byte] = (byte) r1_4 return // succ: main_exit main_exit: === // level1 // Return size: 0 define level1 level1_entry: def r2 // succ: l1 l1: call level2 (retsize: 0;) uses: r2:r2 defs: r1:r1_4 return // succ: level1_exit level1_exit: use r1_4 === // level2 // Return size: 0 define level2 level2_entry: def r2 def Mem0 // succ: l1 l1: r1_5 = Mem0[r2:word32] return // succ: level2_exit level2_exit: use r1_5 === "; #endregion RunTest(sExp, pb.Program); }
public ParameterCollection(AbstractSyntaxNode node, ProgramBuilder context) : base(node, context) { }
public void Setup() { this.pb = new ProgramBuilder(); this.programFlow = new ProgramDataFlow(); this.importReferences = new Dictionary <Address, ImportReference>(); }
public void Setup() { arch = new X86ArchitectureFlat32(); p = new ProgramBuilder(); }