예제 #1
0
        public IILLocal?GenMain(IGenerationContext context)
        {
            var il            = context.IL;
            var needsForProps = context.NeedsForProperties(_implementationType, _arePropertiesAutowired).ToList();

            if (needsForProps.Count > 0)
            {
                var result = il.DeclareLocal(_implementationType);
                context.PushToILStack(context.NeedsForConstructor(_constructorInfo));
                il.Newobj(_constructorInfo).Stloc(result);
                foreach (var need in needsForProps)
                {
                    if (!context.IsResolvableNeed(need))
                    {
                        continue;
                    }
                    var resolvedNeed = context.ResolveNeed(need);
                    if (resolvedNeed.IsCorruptingILStack(context))
                    {
                        var local = resolvedNeed.GenMain(context);
                        if (local == null)
                        {
                            local = il.DeclareLocal(need.ClrType);
                            il.Stloc(local);
                        }

                        il.Ldloc(result);
                        il.Ldloc(local);
                    }
                    else
                    {
                        il.Ldloc(result);
                        var local = resolvedNeed.GenMain(context);
                        if (local != null)
                        {
                            il.Ldloc(local);
                        }
                    }

                    il.Call(need.PropertyInfo !.GetSetMethod(true) !);
                }

                return(result);
            }

            context.PushToILStack(context.NeedsForConstructor(_constructorInfo));
            context.IL.Newobj(_constructorInfo);
            return(null);
        }
예제 #2
0
 internal void Prepare()
 {
     if (MainLocal != null)
     {
         return;
     }
     MainLocal = _context.IL.DeclareLocal(typeof(object[]), "instances");
     _context.PushToILStack(Need.ContainerNeed);
     _context.IL
     .Castclass(typeof(ContainerImpl))
     .Ldfld(() => default(ContainerImpl).Instances)
     .Stloc(MainLocal);
 }
예제 #3
0
 public IILLocal GenMain(IGenerationContext context)
 {
     var localInstances = context.GetSpecific<InstancesLocalGenCtxHelper>().MainLocal;
     var localInstance = context.IL.DeclareLocal(_type, "instance");
     context.IL
         .Ldloc(localInstances)
         .LdcI4(_instanceIndex)
         .LdelemRef()
         .Castclass(typeof(Func<ContainerImpl, object>));
     context.PushToILStack(Need.ContainerNeed);
     context.IL
         .Castclass(typeof(ContainerImpl))
         .Call(() => default(Func<ContainerImpl, object>).Invoke(null))
         .Castclass(_type)
         .Stloc(localInstance);
     return localInstance;
 }
예제 #4
0
        public IILLocal GenMain(IGenerationContext context)
        {
            var localInstances = context.GetSpecific <InstancesLocalGenCtxHelper>().MainLocal;
            var localInstance  = context.IL.DeclareLocal(_type, "instance");

            context.IL
            .Ldloc(localInstances)
            .LdcI4(_instanceIndex)
            .LdelemRef()
            .Castclass(typeof(Func <ContainerImpl, object>));
            context.PushToILStack(Need.ContainerNeed);
            context.IL
            .Castclass(typeof(ContainerImpl))
            .Call(() => default(Func <ContainerImpl, object>).Invoke(null))
            .Castclass(_type)
            .Stloc(localInstance);
            return(localInstance);
        }
예제 #5
0
 public IILLocal GenMain(IGenerationContext context)
 {
     context.PushToILStack(Need.ContainerNeed);
     return null;
 }
예제 #6
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);
        }
예제 #7
0
 public IILLocal GenMain(IGenerationContext context)
 {
     context.PushToILStack(context.NeedsForConstructor(_constructorInfo));
     context.IL.Newobj(_constructorInfo);
     return null;
 }
예제 #8
0
 public IILLocal GenMain(IGenerationContext context)
 {
     context.PushToILStack(Need.ContainerNeed);
     return(null);
 }
예제 #9
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;
 }