/// <summary> /// Initializes the type. /// </summary> protected virtual void InitializeType() { if (Method.IsSpecialName && Method.IsRTSpecialName && Method.IsStatic && Method.Name == ".cctor") { typeInitializer = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>(); if (typeInitializer == null) { return; } typeInitializer.Schedule(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); } }