Esempio n. 1
0
        /*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);
            }
        }
Esempio n. 2
0
 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>();
 }
Esempio n. 3
0
        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;
        }
Esempio n. 4
0
        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);
        }