Exemplo n.º 1
0
        private void GenerateIL()
        {
            IEnumerable <ILocalDefinition> localVariables;
            ushort maxStack;
            IEnumerable <ILocalScope>     iteratorScopes;
            IEnumerable <ILocalScope>     localScopes;
            IEnumerable <INamespaceScope> namespaceScopes;
            IEnumerable <IOperation>      operations;
            IEnumerable <IOperationExceptionInformation> operationExceptionInformation;
            List <ITypeDefinition> /*?*/      privateHelperTypes = this.privateHelperTypes;
            ISynchronizationInformation /*?*/ synchronizationInformation;
            uint size;

            var isNormalized             = this.isNormalized;
            NormalizationChecker checker = null;

            if (!isNormalized)
            {
                //Assuming that most methods are not iterators and do not contain anonymous delegates, it is worth our while to check if this is really the case.
                checker = new NormalizationChecker();
                checker.TraverseChildren(this.Block);
                isNormalized = !checker.foundAnonymousDelegate && !checker.foundYield;
            }

            if (isNormalized)
            {
                IMethodDefinition /*?*/ asyncMethod = null;
                if (this.localScopeProvider != null)
                {
                    var asyncInfo = this.localScopeProvider.GetSynchronizationInformation(this);
                    if (asyncInfo != null)
                    {
                        asyncMethod = asyncInfo.AsyncMethod;
                    }
                }
                var converter = new CodeModelToILConverter(this.host, this.MethodDefinition, this.sourceLocationProvider, asyncMethod, this.iteratorLocalCount);
                converter.TrackExpressionSourceLocations = this.trackExpressionSourceLocations;
                converter.ConvertToIL(this.Block);
                iteratorScopes  = converter.GetIteratorScopes();
                localScopes     = converter.GetLocalScopes();
                localVariables  = converter.GetLocalVariables();
                maxStack        = converter.MaximumStackSizeNeeded;
                size            = converter.GetBodySize();
                namespaceScopes = converter.GetNamespaceScopes();
                operations      = converter.GetOperations();
                operationExceptionInformation = converter.GetOperationExceptionInformation();
                synchronizationInformation    = converter.GetSynchronizationInformation();
            }
            else
            {
                //This object might already be immutable and we are just doing delayed initialization, so make a copy of this.Block.
                var mutableBlock = new CodeDeepCopier(this.host, this.sourceLocationProvider).Copy(this.Block);
                if (checker.foundAnonymousDelegate)
                {
                    var remover = new AnonymousDelegateRemover(this.host, this.sourceLocationProvider);
                    remover.RemoveAnonymousDelegates(this.MethodDefinition, mutableBlock);
                    privateHelperTypes = remover.closureClasses;
                }
                var normalizer     = new MethodBodyNormalizer(this.host, this.sourceLocationProvider);
                var normalizedBody = (SourceMethodBody)normalizer.GetNormalizedSourceMethodBodyFor(this.MethodDefinition, mutableBlock);
                normalizedBody.isNormalized = true;
                iteratorScopes  = normalizedBody.IteratorScopes;
                localScopes     = normalizedBody.LocalScopes;
                localVariables  = normalizedBody.LocalVariables;
                maxStack        = normalizedBody.MaxStack;
                size            = normalizedBody.Size;
                namespaceScopes = normalizedBody.NamespaceScopes;
                operations      = normalizedBody.Operations;
                operationExceptionInformation = normalizedBody.OperationExceptionInformation;
                synchronizationInformation    = normalizedBody.SynchronizationInformation;
                if (privateHelperTypes == null)
                {
                    privateHelperTypes = normalizedBody.PrivateHelperTypes;
                }
                else //this can happen when this source method body has already been partially normalized, for instance by the removal of yield statements.
                {
                    privateHelperTypes.AddRange(normalizedBody.PrivateHelperTypes);
                }
            }

            lock (this) {
                if (this.ilWasGenerated)
                {
                    return;
                }
                this.ilWasGenerated  = true;
                this.iteratorScopes  = iteratorScopes;
                this.localScopes     = localScopes;
                this.localVariables  = localVariables;
                this.maxStack        = maxStack;
                this.namespaceScopes = namespaceScopes;
                this.operations      = operations;
                this.operationExceptionInformation = operationExceptionInformation;
                this.synchronizationInformation    = synchronizationInformation;
                this.privateHelperTypes            = privateHelperTypes;
                this.size = size;
            }
        }
Exemplo n.º 2
0
        private void GenerateIL()
        {
            IEnumerable<ILocalDefinition> localVariables;
              ushort maxStack;
              IEnumerable<ILocalScope> iteratorScopes;
              IEnumerable<ILocalScope> localScopes;
              IEnumerable<INamespaceScope> namespaceScopes;
              IEnumerable<IOperation> operations;
              IEnumerable<IOperationExceptionInformation> operationExceptionInformation;
              List<ITypeDefinition>/*?*/ privateHelperTypes = this.privateHelperTypes;

              var isNormalized = this.isNormalized;
              NormalizationChecker checker = null;
              if (!isNormalized) {
            //Assuming that most methods are not iterators and do not contain anonymous delegates, it is worth our while to check if this is really the case.
            checker = new NormalizationChecker();
            checker.TraverseChildren(this.Block);
            isNormalized = !checker.foundAnonymousDelegate && !checker.foundYield;
              }

              if (isNormalized) {
            var converter = new CodeModelToILConverter(this.host, this.MethodDefinition, this.sourceLocationProvider, this.iteratorLocalCount);
            converter.ConvertToIL(this.Block);
            iteratorScopes = converter.GetIteratorScopes();
            localScopes = converter.GetLocalScopes();
            localVariables = converter.GetLocalVariables();
            maxStack = converter.MaximumStackSizeNeeded;
            namespaceScopes = converter.GetNamespaceScopes();
            operations = converter.GetOperations();
            operationExceptionInformation = converter.GetOperationExceptionInformation();
              } else {
            //This object might already be immutable and we are just doing delayed initialization, so make a copy of this.Block.
            var mutableBlock = new CodeDeepCopier(this.host).Copy(this.Block);
            if (checker.foundAnonymousDelegate) {
              var remover = new AnonymousDelegateRemover(this.host, this.sourceLocationProvider);
              remover.RemoveAnonymousDelegates(this.MethodDefinition, mutableBlock);
              privateHelperTypes = remover.closureClasses;
            }
            var normalizer = new MethodBodyNormalizer(this.host, this.sourceLocationProvider);
            var normalizedBody = (SourceMethodBody)normalizer.GetNormalizedSourceMethodBodyFor(this.MethodDefinition, mutableBlock);
            normalizedBody.isNormalized = true;
            iteratorScopes = normalizedBody.IteratorScopes;
            localScopes = normalizedBody.LocalScopes;
            localVariables = normalizedBody.LocalVariables;
            maxStack = normalizedBody.MaxStack;
            namespaceScopes = normalizedBody.NamespaceScopes;
            operations = normalizedBody.Operations;
            operationExceptionInformation = normalizedBody.OperationExceptionInformation;
            if (privateHelperTypes == null)
              privateHelperTypes = normalizedBody.PrivateHelperTypes;
            else //this can happen when this source method body has already been partially normalized, for instance by the removal of yield statements.
              privateHelperTypes.AddRange(normalizedBody.PrivateHelperTypes);
              }

              lock (this) {
            if (this.ilWasGenerated) return;
            this.ilWasGenerated = true;
            this.iteratorScopes = iteratorScopes;
            this.localScopes = localScopes;
            this.localVariables = localVariables;
            this.maxStack = maxStack;
            this.namespaceScopes = namespaceScopes;
            this.operations = operations;
            this.operationExceptionInformation = operationExceptionInformation;
            this.privateHelperTypes = privateHelperTypes;
              }
        }