/*public static List<ICompiledMethod> JIT(IJITCompiler compiler, string assemblyfile, string[] functionnames, FunctionFilterDelegate functionfilter) * { * if (functionfilter == null) * functionfilter = SameAssemblyFunctionFilter; * * if (!System.IO.File.Exists(assemblyfile)) * throw new Exception("Could not find program file: " + assemblyfile); * * AssemblyDefinition asm = AssemblyFactory.GetAssembly(assemblyfile); * * //TODO: Should support function overloading * Dictionary<string, MethodDefinition> functionLookup = new Dictionary<string, MethodDefinition>(); * foreach (ModuleDefinition mod in asm.Modules) * foreach (TypeDefinition tref in mod.Types) * foreach (MethodDefinition mdef in tref.Methods) * functionLookup.Add(mdef.DeclaringType.FullName + "::" + mdef.Name, mdef); * * Dictionary<MethodReference, string> visitedMethods = new Dictionary<MethodReference, string>(); * List<ICompiledMethod> methods = new List<ICompiledMethod>(); * * Dictionary<Mono.Cecil.AssemblyDefinition, List<Mono.Cecil.MethodReference>> pendingWork = new Dictionary<AssemblyDefinition,List<MethodReference>>(); * * foreach (string name in functionnames) * { * if (!functionLookup.ContainsKey(name)) * throw new Exception("Unable to find function {0} in assembly {1}"); * * MethodDefinition mainfunction = functionLookup[name]; * IR.MethodEntry m = BuildIRTree(mainfunction); * m.ResetVirtualRegisters(); * methods.Add(compiler.JIT(m)); * visitedMethods.Add(mainfunction, null); * * var work = from x in m.FlatInstructionList * let code = x.Instruction.OpCode.Code * where code == Mono.Cecil.Cil.Code.Call || code == Mono.Cecil.Cil.Code.Calli || code == Mono.Cecil.Cil.Code.Callvirt * select ((Mono.Cecil.MethodReference)x.Instruction.Operand); * * foreach (MethodReference mdef in work) * { * if (visitedMethods.ContainsKey(mdef)) * continue; * * visitedMethods.Add(mdef, null); * * if (!functionfilter(null, mainfunction, mdef)) * continue; * * * List<Mono.Cecil.MethodReference> mr; * pendingWork.TryGetValue(mdef.DeclaringType.Module.Assembly, out mr); * if (mr == null) * pendingWork.Add(mdef.DeclaringType.Module.Assembly, mr = new List<MethodReference>()); * mr.Add(mdef); * } * * } * * return methods; * * }*/ /// <summary> /// Function that compiles all functions in an assembly /// </summary> /// <param name="compiler">The compiler that will do the work</param> /// <param name="assemblyfile">The assembly to compile all methods for</param> /// <returns>A list of compiled methods</returns> public static List <ICompiledMethod> JIT(IJITCompiler compiler, string assemblyfile) { if (System.IO.File.Exists(assemblyfile)) { AssemblyDefinition asm = LoadAssemblyFile(assemblyfile); List <ICompiledMethod> methods = new List <ICompiledMethod>(); foreach (ModuleDefinition mod in asm.Modules) { foreach (TypeDefinition tref in mod.Types) { foreach (MethodDefinition mdef in tref.Methods) { IR.MethodEntry root = BuildIRTree(mdef); methods.Add(compiler.JIT(root)); } } } return(methods); } else { throw new Exception("Could not find program file: " + assemblyfile); } }
internal CompiledMethod(MethodEntry method) { m_method = method; m_labels = new Dictionary<string, int>(); m_instructionOffsets = new Dictionary<Mono.Cecil.Cil.Instruction, int>(); m_branches = new List<KeyValuePair<int, Mono.Cecil.Cil.Instruction>>(); m_calls = new List<KeyValuePair<int, Mono.Cecil.MethodReference>>(); m_instructionList = new List<SPEEmulator.OpCodes.Bases.Instruction>(); m_constantLoads = new List<KeyValuePair<int, string>>(); m_stringLoads = new List<KeyValuePair<int, string>>(); m_stack = new Stack<VirtualRegister>(); }
private static IR.MethodEntry BuildIRTree(MethodDefinition mdef) { Stack<IR.InstructionElement> stack = new Stack<IR.InstructionElement>(); List<IR.InstructionElement> roots = new List<IR.InstructionElement>(); int returnElements = 1; if (mdef.ReturnType.ReturnType.FullName == "System.Void") returnElements = 0; foreach (Mono.Cecil.Cil.Instruction x in mdef.Body.Instructions) { IR.InstructionElement[] childnodes; if (x.OpCode.Code == Mono.Cecil.Cil.Code.Ret) childnodes = new IR.InstructionElement[returnElements]; else childnodes = new IR.InstructionElement[NumberOfElementsPoped(x.OpCode.StackBehaviourPop, x.Operand)]; for (int i = childnodes.Length - 1; i >= 0; i--) { System.Diagnostics.Trace.Assert(stack.Count > 0); childnodes[i] = stack.Pop(); } int elementsPushed = NumberOfElementsPushed(x.OpCode.StackBehaviourPush, x.Operand); if (elementsPushed == 0) { if (stack.Count != 0 && x.OpCode.FlowControl != Mono.Cecil.Cil.FlowControl.Next && x.OpCode.FlowControl != Mono.Cecil.Cil.FlowControl.Call) throw new InvalidProgramException(); roots.Add(new IR.InstructionElement(mdef, childnodes, x)); } else { IR.InstructionElement ins = new IR.InstructionElement(mdef, childnodes, x); for(int i = 0; i < elementsPushed; i++) stack.Push(ins); } } if (stack.Count != 0) throw new InvalidProgramException(); IR.MethodEntry m = new IR.MethodEntry(mdef) { Childnodes = roots.ToArray() }; m.ResetVirtualRegisters(); return m; }
private static IR.MethodEntry BuildIRTree(MethodDefinition mdef) { Stack <IR.InstructionElement> stack = new Stack <IR.InstructionElement>(); List <IR.InstructionElement> roots = new List <IR.InstructionElement>(); int returnElements = 1; if (mdef.ReturnType.ReturnType.FullName == "System.Void") { returnElements = 0; } foreach (Mono.Cecil.Cil.Instruction x in mdef.Body.Instructions) { IR.InstructionElement[] childnodes; if (x.OpCode.Code == Mono.Cecil.Cil.Code.Ret) { childnodes = new IR.InstructionElement[returnElements]; } else { childnodes = new IR.InstructionElement[NumberOfElementsPoped(x.OpCode.StackBehaviourPop, x.Operand)]; } for (int i = childnodes.Length - 1; i >= 0; i--) { System.Diagnostics.Trace.Assert(stack.Count > 0); childnodes[i] = stack.Pop(); } int elementsPushed = NumberOfElementsPushed(x.OpCode.StackBehaviourPush, x.Operand); if (elementsPushed == 0) { if (stack.Count != 0 && x.OpCode.FlowControl != Mono.Cecil.Cil.FlowControl.Next && x.OpCode.FlowControl != Mono.Cecil.Cil.FlowControl.Call) { throw new InvalidProgramException(); } roots.Add(new IR.InstructionElement(mdef, childnodes, x)); } else { IR.InstructionElement ins = new IR.InstructionElement(mdef, childnodes, x); for (int i = 0; i < elementsPushed; i++) { stack.Push(ins); } } } if (stack.Count != 0) { throw new InvalidProgramException(); } IR.MethodEntry m = new IR.MethodEntry(mdef) { Childnodes = roots.ToArray() }; m.ResetVirtualRegisters(); return(m); }