Example #1
0
    internal LockReplacer(SourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null);
      this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
      this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null);
      this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null);
      this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null);
      var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
        this.host.NameTable.GetNameFor("Threading"));
      var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
        isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
      var parameters = new IParameterTypeInformation[2];
      this.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);
      this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
        this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);

    }
Example #2
0
        internal LockReplacer(SourceMethodBody sourceMethodBody)
        {
            Contract.Requires(sourceMethodBody != null);
            this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null);
            this.sourceLocationProvider     = sourceMethodBody.sourceLocationProvider;
            this.numberOfReferencesToLocal  = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null);
            this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null);
            this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null);
            var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace,
                                                                             this.host.NameTable.GetNameFor("Threading"));
            var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0,
                                                                              isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive);
            var parameters = new IParameterTypeInformation[2];

            this.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);
            this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid,
                                                   this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject);
        }
Example #3
0
        /// <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;
        }