Example #1
0
        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;
        }
Example #2
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;
        }