void GenerateBody() { _registration.GenInitialization(this); var local = _registration.GenMain(this); if (local != null) { IL.Ldloc(local); } IL.Ret(); }
public IILLocal GenMain(IGenerationContext context) { var backupCtx = context.BuildContext; context.BuildContext = _buildCtx !; var il = context.IL; var buildCRegLocals = context.GetSpecific <BuildCRegLocals>(); var localSingleton = buildCRegLocals.Get(this); if (localSingleton != null) { return(localSingleton); } var localSingletons = context.GetSpecific <SingletonsLocal>().MainLocal; var safeImplementationType = _implementationType.IsPublic ? _implementationType : typeof(object); localSingleton = il.DeclareLocal(safeImplementationType, "singleton"); var obj = context.Container.Singletons[_singletonIndex]; if (obj != null) { il .Ldloc(localSingletons !) .LdcI4(_singletonIndex) .LdelemRef() .Castclass(_implementationType) .Stloc(localSingleton); return(localSingleton); } var localLockTaken = il.DeclareLocal(typeof(bool), "lockTaken"); var localLock = il.DeclareLocal(typeof(object), "lock"); var labelNull1 = il.DefineLabel(); var labelNotNull2 = il.DefineLabel(); var labelNotTaken = il.DefineLabel(); bool boolPlaceholder = false; il .Ldloc(localSingletons !) .LdcI4(_singletonIndex) .LdelemRef() .Dup() .Castclass(safeImplementationType) .Stloc(localSingleton) .Brtrue(labelNull1) .LdcI4(0) .Stloc(localLockTaken); context.PushToILStack(Need.ContainerNeed); il .Castclass(typeof(ContainerImpl)) .Ldfld(() => default(ContainerImpl).SingletonLocks) .LdcI4(_singletonIndex) .LdelemRef() .Stloc(localLock) .Try() .Ldloc(localLock) .Ldloca(localLockTaken) .Call(() => Monitor.Enter(null, ref boolPlaceholder)) .Ldloc(localSingletons) .LdcI4(_singletonIndex) .LdelemRef() .Dup() .Castclass(safeImplementationType) .Stloc(localSingleton) .Brtrue(labelNotNull2); buildCRegLocals.Push(); var nestedLocal = _wrapping.GenMain(context); if (nestedLocal != null) { il.Ldloc(nestedLocal); } buildCRegLocals.Pop(); il .Stloc(localSingleton) .Ldloc(localSingletons) .LdcI4(_singletonIndex) .Ldloc(localSingleton) .StelemRef() .Mark(labelNotNull2) .Finally() .Ldloc(localLockTaken) .BrfalseS(labelNotTaken) .Ldloc(localLock) .Call(() => Monitor.Exit(null)) .Mark(labelNotTaken) .EndTry() .Mark(labelNull1); buildCRegLocals.Add(this, localSingleton); context.BuildContext = backupCtx; return(localSingleton); }