Beispiel #1
0
        /// <summary>
        /// Link time code generator used to compile dynamically created methods during link time.
        /// </summary>
        /// <param name="compiler">The assembly compiler used to compile this method.</param>
        /// <param name="methodName">The name of the created method.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception>
        public static CompilerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet)
        {
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }
            if (methodName == null)
            {
                throw new ArgumentNullException(@"methodName");
            }
            if (methodName.Length == 0)
            {
                throw new ArgumentException(@"Invalid method name.");
            }

            // Create the type if we need to.
            CompilerGeneratedType type = compilerGeneratedType;

            if (type == null)
            {
                type = compilerGeneratedType = new CompilerGeneratedType(compiler.Assembly, @"Mosa.Tools.Compiler", @"LinkerGenerated");
            }

            // Create the method
            // HACK: <$> prevents the method from being called from CIL
            CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, "<$>" + methodName, type);

            type.Methods.Add(method);

            LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, method, instructionSet);

            methodCompiler.Compile();
            return(method);
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            _ctx.AppendInstruction(IR.Instruction.CallInstruction);
            _ctx.InvokeTarget = compiler.Assembly.EntryPoint;
            _ctx.AppendInstruction(IR.Instruction.EpilogueInstruction);
            _ctx.Other = 0;

            _method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", InstructionSet);
        }
        private void CompileObjectEquals(string typeName)
        {
            var type = new CompilerGeneratedType(compiler.Assembly, @"System", typeName);

            // Create the method
            CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, @"Equals", type);
            method.Parameters.Add(new RuntimeParameter(null, @"obj", 0, ParameterAttributes.In));
            method.SetSignature(new MethodSignature(BuiltInSigType.Boolean, new SigType[] { BuiltInSigType.Object }));
            type.AddMethod(method);

            this.Compile(method);
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            if (compiler == null)
            {
                throw new ArgumentNullException(@"compiler");
            }

            IAssemblyLinker linker = compiler.Pipeline.Find <IAssemblyLinker>();

            Debug.Assert(linker != null, @"No linker??");

            if (!secondStage)
            {
                IntPtr entryPoint = WriteMultibootEntryPoint(linker);
                WriteMultibootHeader(compiler, linker, entryPoint);
                secondStage = true;
            }
            else
            {
                TypeInitializerSchedulerStage typeInitializerSchedulerStage = compiler.Pipeline.Find <TypeInitializerSchedulerStage>();

                SigType I4 = new SigType(CilElementType.I4);

                RegisterOperand ecx = new RegisterOperand(I4, GeneralPurposeRegister.ECX);
                RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX);
                RegisterOperand ebx = new RegisterOperand(I4, GeneralPurposeRegister.EBX);

                InstructionSet instructionSet = new InstructionSet(16);
                Context        ctx            = new Context(instructionSet, -1);

                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new ConstantOperand(I4, 0x200000));
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x0)), eax);
                ctx.AppendInstruction(CPUx86.Instruction.MovInstruction, new MemoryOperand(I4, ecx.Register, new IntPtr(0x4)), ebx);
                ctx.AppendInstruction(IR.Instruction.CallInstruction);
                ctx.InvokeTarget = typeInitializerSchedulerStage.Method;
                ctx.AppendInstruction(CPUx86.Instruction.NopInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.NopInstruction);
                ctx.AppendInstruction(CPUx86.Instruction.RetInstruction);

                CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"MultibootInit", instructionSet);
                linker.EntryPoint = linker.GetSymbol(method);
            }
        }
        /// <summary>
        /// Link time code generator used to compile dynamically created methods during link time.
        /// </summary>
        /// <param name="compiler">The assembly compiler used to compile this method.</param>
        /// <param name="methodName">The name of the created method.</param>
        /// <param name="instructionSet">The instruction set.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception>
        public static CompilerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet)
        {
            if (compiler == null)
                throw new ArgumentNullException(@"compiler");
            if (methodName == null)
                throw new ArgumentNullException(@"methodName");
            if (methodName.Length == 0)
                throw new ArgumentException(@"Invalid method name.");

            // Create the type if we need to.
            if (compilerGeneratedType == null)
                compilerGeneratedType = new CompilerGeneratedType(compiler.Assembly, @"Mosa.Tools.Compiler", @"LinkerGenerated");

            // Create the method
            // HACK: <$> prevents the method from being called from CIL
            CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, "<$>" + methodName, compilerGeneratedType);
            compilerGeneratedType.AddMethod(method);

            LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(), method, instructionSet);
            methodCompiler.Compile();
            return method;
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        public void Run()
        {
            _ctx.AppendInstruction(IR.Instruction.CallInstruction, this.compiler.Assembly.EntryPoint);
            _ctx.AppendInstruction(IR.Instruction.EpilogueInstruction);
            _ctx.Other = 0;

            _method = LinkTimeCodeGenerator.Compile(this.compiler, @"AssemblyInit", InstructionSet);
        }
        private RuntimeMethod GenerateMethod(string @namespace, string typeName, string methodName)
        {
            var type = new CompilerGeneratedType(compiler.Assembly, @namespace, typeName);

            // Create the method
            CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, methodName, type);
            type.AddMethod(method);

            return method;
        }
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        /// <param name="compiler">The compiler context to perform processing in.</param>
        public void Run(AssemblyCompiler compiler)
        {
            _ctx.AppendInstruction(IR.Instruction.CallInstruction);
            _ctx.InvokeTarget = compiler.Assembly.EntryPoint;
            _ctx.AppendInstruction(IR.Instruction.EpilogueInstruction);
            _ctx.Other = 0;

            _method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", InstructionSet);
        }