public static void EmitStaticConstructorCheck(LIRMethod m, IRType targetType, IRType curType, bool forceEmit = false) { if (targetType.HasStaticConstructor && (forceEmit || targetType != curType)) { var con = targetType.StaticConstructor; if ( ( con.Instructions.Count == 1 && con.Instructions[0].Opcode == IROpcode.Return ) || ( con.Instructions.Count == 2 && con.Instructions[0].Opcode == IROpcode.Nop && con.Instructions[1].Opcode == IROpcode.Return ) ) { // We don't need a static constructor call } else { StaticConstructorCalledEmittableDataItem d = null; if (!KnownStaticConstructors.TryGetValue(targetType, out d)) { d = new StaticConstructorCalledEmittableDataItem(targetType); m.CompileUnit.AddData(d); KnownStaticConstructors.Add(targetType, d); } new LIRInstructions.Comment(m, "Static Constructor Check"); var c = m.RequestLocal(targetType.Assembly.AppDomain.System_Boolean); new LIRInstructions.Move(m, new Indirect(d.Label), c, targetType.Assembly.AppDomain.System_Boolean); Label called = new Label(); new LIRInstructions.BranchTrue(m, c, called); m.ReleaseLocal(c); new LIRInstructions.Move(m, (LIRImm)1, new Indirect(d.Label), targetType.Assembly.AppDomain.System_Boolean); new LIRInstructions.Call(m, con); m.MarkLabel(called); } } }