Exemplo n.º 1
0
        void GenerateBody()
        {
            _registration.GenInitialization(this);
            var local = _registration.GenMain(this);

            if (local != null)
            {
                IL.Ldloc(local);
            }
            IL.Ret();
        }
Exemplo n.º 2
0
        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);
        }