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)); }
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; } }
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; } }
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); }