Example #1
0
        public static IModule RewriteModule(IMetadataHost host, ILocalScopeProvider localScopeProvider, ISourceLocationProvider sourceLocationProvider, IModule module)
        {
            var rew = new MyILRewriter(host, localScopeProvider, sourceLocationProvider);
            var me  = new RewriteStoreLocal(host, rew);

            return(me.Rewrite(module));
        }
Example #2
0
        public override void RewriteChildren(MethodBody methodBody)
        {
            this.currentMethod = methodBody.MethodDefinition;

            var compilerGenerated = TypeHelper.IsCompilerGenerated(currentMethod.ContainingTypeDefinition);
            // Method contracts from iterators (and async methods) end up in the MoveNext method in the compiler generated
            // class that implements the state machine. So they need to be treated specially.
            var isMoveNextMethodInCompilerGeneratedMethod = compilerGenerated && currentMethod.Name == this.MoveNextName;

            if ((compilerGenerated && !isMoveNextMethodInCompilerGeneratedMethod) || this.IsIteratorOrAsyncMethod(currentMethod))
            {
                return;
            }

            uint lastOffset;

            if (!TryGetOffsetOfLastContractCall(methodBody.Operations, out lastOffset))
            {
                return;
            }
            // And here is the special handling: currently the contract extractors expect to find the contracts
            // in the MoveNext method. So don't move them to the iterator/async method, just convert all of the
            // contracts in the MoveNext method into the three-arg version and keep the whole method body. No
            // point trying to truncate it since the contracts are not in a prefix of the instructions, but are
            // buried within the state machine.
            if (isMoveNextMethodInCompilerGeneratedMethod)
            {
                var lastIndex = methodBody.Operations.Count - 1;
                lastOffset = methodBody.Operations[lastIndex].Offset;
            }

            try {
                var ilRewriter          = new MyILRewriter(this.host, this, lastOffset, isMoveNextMethodInCompilerGeneratedMethod);
                var rewrittenMethodBody = ilRewriter.Rewrite(methodBody);

                var locals = rewrittenMethodBody.LocalVariables;

                methodBody.LocalVariables = locals as List <ILocalDefinition> ?? new List <ILocalDefinition>(locals);

                var ops = rewrittenMethodBody.Operations;
                methodBody.Operations = ops as List <IOperation> ?? new List <IOperation>(ops);

                methodBody.OperationExceptionInformation = new List <IOperationExceptionInformation>();

                methodBody.MaxStack = rewrittenMethodBody.MaxStack;
                methodBody.MaxStack++;

                //// REVIEW: Is this okay to do here? Or does it need to be done in the IL Rewriter?
                //#region All done: add return statement
                //if (!isMoveNextMethodInCompilerGeneratedMethod) {
                //  if (currentMethod.Type.TypeCode != PrimitiveTypeCode.Void) {
                //    LocalDefinition ld = new LocalDefinition() {
                //      Type = currentMethod.Type,
                //    };
                //    if (methodBody.LocalVariables == null) methodBody.LocalVariables = new List<ILocalDefinition>();
                //    methodBody.LocalVariables.Add(ld);
                //    methodBody.Operations.Add(new Operation(){  OperationCode= OperationCode.Ldloc, Value = ld, });
                //    methodBody.MaxStack++;
                //  }
                //  methodBody.Operations.Add(new Operation() { OperationCode = OperationCode.Ret, });
                //}
                //#endregion All done: add return statement

                return;
            } catch (ExtractorException) {
                Console.WriteLine("Warning: Unable to extract contract from the method '{0}'.",
                                  MemberHelper.GetMemberSignature(currentMethod, NameFormattingOptions.SmartTypeName));
                methodBody.OperationExceptionInformation = new List <IOperationExceptionInformation>();
                methodBody.Operations = new List <IOperation>();
                methodBody.MaxStack   = 0;
                return;
            }
        }
Example #3
0
    public override void RewriteChildren(MethodBody methodBody) {

      this.currentMethod = methodBody.MethodDefinition;

      var compilerGenerated = TypeHelper.IsCompilerGenerated(currentMethod.ContainingTypeDefinition);
      // Method contracts from iterators (and async methods) end up in the MoveNext method in the compiler generated
      // class that implements the state machine. So they need to be treated specially.
      var isMoveNextMethodInCompilerGeneratedMethod = compilerGenerated && currentMethod.Name == this.MoveNextName;

      if ((compilerGenerated && !isMoveNextMethodInCompilerGeneratedMethod) || this.IsIteratorOrAsyncMethod(currentMethod)) {
        return;
      }

      uint lastOffset;
      if (!TryGetOffsetOfLastContractCall(methodBody.Operations, out lastOffset))
        return;
      // And here is the special handling: currently the contract extractors expect to find the contracts
      // in the MoveNext method. So don't move them to the iterator/async method, just convert all of the
      // contracts in the MoveNext method into the three-arg version and keep the whole method body. No
      // point trying to truncate it since the contracts are not in a prefix of the instructions, but are
      // buried within the state machine.
      if (isMoveNextMethodInCompilerGeneratedMethod) {
        var lastIndex = methodBody.Operations.Count - 1;
        lastOffset = methodBody.Operations[lastIndex].Offset;
      }

      try {

        var ilRewriter = new MyILRewriter(this.host, this, lastOffset, isMoveNextMethodInCompilerGeneratedMethod);
        var rewrittenMethodBody = ilRewriter.Rewrite(methodBody);

        var locals = rewrittenMethodBody.LocalVariables;

        methodBody.LocalVariables = locals as List<ILocalDefinition> ?? new List<ILocalDefinition>(locals);

        var ops = rewrittenMethodBody.Operations;
        methodBody.Operations = ops as List<IOperation> ?? new List<IOperation>(ops);

        methodBody.OperationExceptionInformation = new List<IOperationExceptionInformation>();

        methodBody.MaxStack = rewrittenMethodBody.MaxStack;
        methodBody.MaxStack++;

        //// REVIEW: Is this okay to do here? Or does it need to be done in the IL Rewriter?
        //#region All done: add return statement
        //if (!isMoveNextMethodInCompilerGeneratedMethod) {
        //  if (currentMethod.Type.TypeCode != PrimitiveTypeCode.Void) {
        //    LocalDefinition ld = new LocalDefinition() {
        //      Type = currentMethod.Type,
        //    };
        //    if (methodBody.LocalVariables == null) methodBody.LocalVariables = new List<ILocalDefinition>();
        //    methodBody.LocalVariables.Add(ld);
        //    methodBody.Operations.Add(new Operation(){  OperationCode= OperationCode.Ldloc, Value = ld, });
        //    methodBody.MaxStack++;
        //  }
        //  methodBody.Operations.Add(new Operation() { OperationCode = OperationCode.Ret, });
        //}
        //#endregion All done: add return statement

        return;

      } catch (ExtractorException) {
        Console.WriteLine("Warning: Unable to extract contract from the method '{0}'.",
          MemberHelper.GetMemberSignature(currentMethod, NameFormattingOptions.SmartTypeName));
        methodBody.OperationExceptionInformation = new List<IOperationExceptionInformation>();
        methodBody.Operations = new List<IOperation>();
        methodBody.MaxStack = 0;
        return;
      }
    }
Example #4
0
 public static IModule RewriteModule(IMetadataHost host, ILocalScopeProvider localScopeProvider, ISourceLocationProvider sourceLocationProvider, IModule module) {
   var rew = new MyILRewriter(host, localScopeProvider, sourceLocationProvider);
   var me = new RewriteStoreLocal(host, rew);
   return me.Rewrite(module);
 }