コード例 #1
0
 public CallCloseOrDisposeAnalysisVisitor(IMetadataHost host, PdbReader pdbReader)
 {
     this.host        = host;
     this.pdbReader   = pdbReader;
     this.iDisposable = new NamespaceTypeReference(this.host, this.host.PlatformType.SystemObject.ContainingUnitNamespace,
                                                   this.host.NameTable.GetNameFor("IDisposable"), 0, false, false, true, PrimitiveTypeCode.Reference);
 }
コード例 #2
0
ファイル: Visitor.cs プロジェクト: riverar/devtools
        /// <summary>
        /// Generates IL for the specified resource use statement.
        /// </summary>
        /// <param name="resourceUseStatement">The resource use statement.</param>
        public override void TraverseChildren(IResourceUseStatement resourceUseStatement)
        {
            this.EmitSequencePoint(resourceUseStatement.Locations);
              var systemIDisposable = new NamespaceTypeReference(this.host, this.host.PlatformType.SystemObject.ContainingUnitNamespace,
            this.host.NameTable.GetNameFor("IDisposable"), 0, isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
              var dispose = new MethodReference(this.host, systemIDisposable, CallingConvention.Default, this.host.PlatformType.SystemVoid,
            this.host.NameTable.GetNameFor("Dispose"), 0, Enumerable<IParameterTypeInformation>.Empty);

              //Get resource into a local
              ILocalDefinition resourceLocal;
              var localDeclaration = resourceUseStatement.ResourceAcquisitions as ILocalDeclarationStatement;
              if (localDeclaration != null) {
            resourceLocal = localDeclaration.LocalVariable;
            this.Traverse(localDeclaration.InitialValue);
              } else {
            var expressionStatement = (IExpressionStatement)resourceUseStatement.ResourceAcquisitions;
            this.Traverse(expressionStatement.Expression);
            resourceLocal = new TemporaryVariable(systemIDisposable, this.method);
              }
              this.VisitAssignmentTo(resourceLocal);

              //try
              var savedCurrentTryCatch = this.currentTryCatch;
              this.currentTryCatch = resourceUseStatement;
              var savedCurrentTryCatchFinallyEnd = this.currentTryCatchFinallyEnd;
              this.currentTryCatchFinallyEnd = new ILGeneratorLabel();
              this.generator.BeginTryBody();
              this.Traverse(resourceUseStatement.Body);
              if (!this.lastStatementWasUnconditionalTransfer)
            this.generator.Emit(OperationCode.Leave, this.currentTryCatchFinallyEnd);

              //finally
              this.generator.BeginFinallyBlock();
              var endOfFinally = new ILGeneratorLabel();
              if (!resourceLocal.Type.IsValueType) {
            this.generator.Emit(OperationCode.Ldloc, resourceLocal);
            this.generator.Emit(OperationCode.Brfalse_S, endOfFinally);
              }
              this.generator.Emit(OperationCode.Ldloc, resourceLocal);
              this.generator.Emit(OperationCode.Callvirt, dispose);
              this.generator.MarkLabel(endOfFinally);
              this.generator.Emit(OperationCode.Endfinally);
              this.generator.EndTryBody();
              this.generator.MarkLabel(this.currentTryCatchFinallyEnd);
              this.currentTryCatchFinallyEnd = savedCurrentTryCatchFinallyEnd;
              this.currentTryCatch = savedCurrentTryCatch;
              this.lastStatementWasUnconditionalTransfer = false;
        }
コード例 #3
0
ファイル: Visitor.cs プロジェクト: riverar/devtools
        private void GenerateDownLevelLockStatement(ILockStatement lockStatement)
        {
            var systemThreading = new NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
            this.host.NameTable.GetNameFor("Threading"));
              var systemThreadingMonitor = new NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
            isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
              var parameters = new IParameterTypeInformation[2];
              var monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
            this.host.NameTable.GetNameFor("Enter"), 0, this.host.PlatformType.SystemObject);
              var monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
            this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);

              this.EmitSequencePoint(lockStatement.Locations);
              var guardObject = new TemporaryVariable(lockStatement.Guard.Type, this.method);
              this.Traverse(lockStatement.Guard);
              this.generator.Emit(OperationCode.Dup); this.StackSize++;
              this.VisitAssignmentTo(guardObject);
              this.generator.Emit(OperationCode.Call, monitorEnter);
              this.StackSize--;
              //try
              var savedCurrentTryCatch = this.currentTryCatch;
              this.currentTryCatch = lockStatement;
              var savedCurrentTryCatchFinallyEnd = this.currentTryCatchFinallyEnd;
              this.currentTryCatchFinallyEnd = new ILGeneratorLabel();
              this.generator.BeginTryBody();
              this.Traverse(lockStatement.Body);
              if (!this.lastStatementWasUnconditionalTransfer)
            this.generator.Emit(OperationCode.Leave, this.currentTryCatchFinallyEnd);
              //finally
              this.generator.BeginFinallyBlock();
              //if (status)
              this.LoadLocal(guardObject);
              this.generator.Emit(OperationCode.Call, monitorExit);
              this.StackSize--;
              //monitor exit
              this.generator.Emit(OperationCode.Endfinally);
              this.generator.EndTryBody();
              this.generator.MarkLabel(this.currentTryCatchFinallyEnd);
              this.currentTryCatchFinallyEnd = savedCurrentTryCatchFinallyEnd;
              this.currentTryCatch = savedCurrentTryCatch;
              this.lastStatementWasUnconditionalTransfer = false;
        }
コード例 #4
0
ファイル: Visitor.cs プロジェクト: riverar/devtools
        /// <summary>
        /// Generates IL for the specified lock statement.
        /// </summary>
        /// <param name="lockStatement">The lock statement.</param>
        public override void TraverseChildren(ILockStatement lockStatement)
        {
            if (this.host.SystemCoreAssemblySymbolicIdentity.Version.Major < 4) {
            this.GenerateDownLevelLockStatement(lockStatement);
            return;
              }
              var systemThreading = new NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
            this.host.NameTable.GetNameFor("Threading"));
              var systemThreadingMonitor = new NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
            isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
              var parameters = new IParameterTypeInformation[2];
              var monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
            this.host.NameTable.GetNameFor("Enter"), 0, parameters);
              parameters[0] = new SimpleParameterTypeInformation(monitorEnter, 0, this.host.PlatformType.SystemObject);
              parameters[1] = new SimpleParameterTypeInformation(monitorEnter, 1, this.host.PlatformType.SystemBoolean, isByReference: true);
              var monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
            this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);

              this.EmitSequencePoint(lockStatement.Locations);
              var guardObject = new TemporaryVariable(lockStatement.Guard.Type, this.method);
              var lockTaken = new TemporaryVariable(this.host.PlatformType.SystemBoolean, this.method);
              //try
              var savedCurrentTryCatch = this.currentTryCatch;
              this.currentTryCatch = lockStatement;
              var savedCurrentTryCatchFinallyEnd = this.currentTryCatchFinallyEnd;
              this.currentTryCatchFinallyEnd = new ILGeneratorLabel();
              this.generator.BeginTryBody();
              this.Traverse(lockStatement.Guard);
              this.generator.Emit(OperationCode.Dup); this.StackSize++;
              this.VisitAssignmentTo(guardObject);
              this.LoadAddressOf(lockTaken, null);
              this.generator.Emit(OperationCode.Call, monitorEnter);
              this.StackSize-=2;
              this.Traverse(lockStatement.Body);
              if (!this.lastStatementWasUnconditionalTransfer)
            this.generator.Emit(OperationCode.Leave, this.currentTryCatchFinallyEnd);
              //finally
              this.generator.BeginFinallyBlock();
              //if (status)
              var endIf = new ILGeneratorLabel();
              this.LoadLocal(lockTaken);
              this.generator.Emit(OperationCode.Brfalse_S, endIf);
              this.StackSize--;
              this.LoadLocal(guardObject);
              this.generator.Emit(OperationCode.Call, monitorExit);
              this.StackSize--;
              this.generator.MarkLabel(endIf);
              //monitor exit
              this.generator.Emit(OperationCode.Endfinally);
              this.generator.EndTryBody();
              this.generator.MarkLabel(this.currentTryCatchFinallyEnd);
              this.currentTryCatchFinallyEnd = savedCurrentTryCatchFinallyEnd;
              this.currentTryCatch = savedCurrentTryCatch;
              this.lastStatementWasUnconditionalTransfer = false;
        }