/// <summary>
        /// Genereates a jitted method for the given method body
        /// </summary>
        /// <param name="name">The name of the method</param>
        /// <param name="methodBody">The method body</param>
        /// <param name="isFunction">Indicates if the given method is a function or inline code.</param>
        /// <returns>A reference to the jited method or null if not jited</returns>
        public MethodInfo GenerateMethod(string name, Instruction[] methodBody, bool isFunction = false)
        {
            var jitedMethod = new DynamicMethod(
                name,
                typeof(void),
                new Type[] { typeof(InternalVMData) },
                typeof(PartialJITCompiler));

            var generatorData = new MethodGeneratorData(jitedMethod.GetILGenerator(), methodBody.Length);

            for (int i = 0; i < methodBody.Length; i++)
            {
                generatorData.ILGenerator.MarkLabel(generatorData.GetLabel(i));
                bool emited = this.EmitInstruction(i, methodBody[i].Data, generatorData);

                if (!emited)
                {
                    return(null);
                }
            }

            if (!isFunction)
            {
                jitedMethod.GetILGenerator().Emit(OpCodes.Ret);
            }

            return(jitedMethod);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Emites the given instruction
        /// </summary>
        /// <param name="index">The index of the instruction</param>
        /// <param name="instructionData">The data of the instruction</param>
        /// <param name="generatorData">The generator data</param>
        /// <returns>True if emited else false</returns>
        public bool EmitInstruction(int index, int instructionData, MethodGeneratorData generatorData)
        {
            //Read the opcode
            OperationCodes opCode = (OperationCodes)(instructionData & 0x3F);

            //Find the emiter
            InstructionEmiter emiter = null;

            if (this.instructionEmiters.TryGetValue(opCode, out emiter))
            {
                switch (emiter.InstructionFormat)
                {
                case InstructionFormat.IFormat:
                    this.DecodeAndEmitIFormat(index, instructionData, generatorData, emiter);
                    break;

                case InstructionFormat.RFormat:
                    this.DecodeAndEmitRFormat(index, instructionData, generatorData, emiter);
                    break;

                case InstructionFormat.JFormat:
                    this.DecodeAndEmitJFormat(index, instructionData, generatorData, emiter);
                    break;
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decodes and emites the given J-format instruction
        /// </summary>
        /// <param name="index">The index of the instruction</param>
        /// <param name="instructionData">The instruction data</param>
        /// <param name="generatorData">The generator data</param>
        /// <param name="emiter">The emiter</param>
        private void DecodeAndEmitJFormat(int index, int instructionData, MethodGeneratorData generatorData, InstructionEmiter emiter)
        {
            //Decode and execute it
            JFormatInstruction instruction = JFormatInstruction.Decode(instructionData);

            emiter.JFormatInstructionEmiter(index, instruction, generatorData);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Decodes and emits the given R-format instruction
        /// </summary>
        /// <param name="index">The index of the instruction</param>
        /// <param name="instructionData">The instruction data</param>
        /// <param name="generatorData">The method generator data</param>
        /// <param name="emiter">The executor</param>
        private void DecodeAndEmitRFormat(int index, int instructionData, MethodGeneratorData generatorData, InstructionEmiter emiter)
        {
            //Decode it
            RFormatInstruction instruction = RFormatInstruction.Decode(instructionData);

            //Find the R-format emiter
            RFormatInstructionEmiter opxEmiter = null;

            //Check if maskers exists
            if (emiter.RFormatOpxMaskers.Count == 0)
            {
                if (emiter.RFormatInstructionEmiters.TryGetValue(instruction.OpxCode, out opxEmiter))
                {
                    opxEmiter(index, instruction, generatorData);
                }
            }
            else
            {
                //Loop until an executor is found
                foreach (int currentMask in emiter.RFormatOpxMaskers)
                {
                    int opxCode = instruction.OpxCode & currentMask;

                    if (emiter.RFormatInstructionEmiters.TryGetValue(opxCode, out opxEmiter))
                    {
                        opxEmiter(index, instruction, generatorData);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates the body for the given function
        /// </summary>
        /// <param name="funcRef">The function reference</param>
        /// <param name="funcBody">The function body</param>
        private void GenerateFunctionBody(DynamicMethod funcRef, Instruction[] funcBody)
        {
            var generatorData = new MethodGeneratorData(funcRef.GetILGenerator(), funcBody.Length);
            var gen           = generatorData.ILGenerator;

            for (int i = 0; i < funcBody.Length; i++)
            {
                generatorData.ILGenerator.MarkLabel(generatorData.GetLabel(i));
                this.EmitInstruction(i, funcBody[i].Data, generatorData);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Generates a jitted program for the given instructions
        /// </summary>
        /// <param name="name">The name of the program</param>
        /// <param name="instructions">The instructions</param>
        /// <param name="functionTable">The function entry points and their sizes</param>
        /// <returns>A reference to the jitted method or null if not jitted</returns>
        public MethodInfo GenerateProgram(string name, Instruction[] instructions, IDictionary <uint, int> functionTable)
        {
            var jittedProgram = new DynamicMethod(
                name,
                typeof(void),
                new Type[] { typeof(InternalVMData) },
                typeof(FullJITCompiler));

            var generatorData = new MethodGeneratorData(jittedProgram.GetILGenerator(), instructions.Length);

            //Generate func ref for all functions
            foreach (int currentFunc in functionTable.Keys)
            {
                //Create the new function
                var funcRef = new DynamicMethod(
                    "func_at_" + currentFunc,
                    typeof(void),
                    new Type[] { typeof(InternalVMData) },
                    typeof(FullJITCompiler));

                generatorData.FunctionTable.Add(currentFunc, funcRef);
            }

            for (int i = 0; i < instructions.Length; i++)
            {
                uint currentInstNum = (uint)i;

                //Check if function
                if (functionTable.ContainsKey(currentInstNum))
                {
                    int funcSize = functionTable[currentInstNum];

                    //Get the func ref and jit its body
                    var funcRef = (DynamicMethod)generatorData.FunctionTable[i];

                    Instruction[] funcBody = new Instruction[funcSize];
                    Array.Copy(instructions, i, funcBody, 0, funcSize);
                    this.GenerateFunctionBody(funcRef, funcBody);

                    i += funcSize - 1;
                }
                else
                {
                    generatorData.ILGenerator.MarkLabel(generatorData.GetLabel(i));
                    this.EmitInstruction(i, instructions[i].Data, generatorData);
                }
            }

            jittedProgram.GetILGenerator().Emit(OpCodes.Ret);

            return(jittedProgram);
        }