private void TransformPInvokeMethodDefinitionToImplementedMethodDefinition(MethodDefinition methodDefinition) { methodDefinition.IsPlatformInvoke = false; methodDefinition.IsExternal = false; methodDefinition.PreserveSignature = false; var ilGenerator = new ILGenerator(this.host, methodDefinition); var label = new ILGeneratorLabel(); var transformationMetadata = this.metadataProvider.Retrieve(methodDefinition); var fieldDef = transformationMetadata.FunctionPointer; var locals = new List <ILocalDefinition>(); var paramToLocalMap = new Dictionary <IParameterDefinition, ILocalDefinition>(); ilGenerator.Emit(OperationCode.Ldsfld, fieldDef); ilGenerator.Emit(OperationCode.Ldsfld, this.intPtrZero); ilGenerator.Emit(OperationCode.Call, this.intPtrOpEquality); ilGenerator.Emit(OperationCode.Brfalse_S, label); ilGenerator.Emit(OperationCode.Call, transformationMetadata.InitializeMethod); ilGenerator.MarkLabel(label); this.LoadArguments(locals, paramToLocalMap, ilGenerator, methodDefinition.ParameterCount, i => methodDefinition.Parameters[i], methodDefinition.PlatformInvokeData); ilGenerator.Emit(OperationCode.Ldsfld, fieldDef); ilGenerator.Emit(OperationCode.Call, transformationMetadata.NativeMethod); this.ReturnMarshalling(ilGenerator, methodDefinition); this.PostprocessNonBlittableArrayArguments(methodDefinition, locals, paramToLocalMap, ilGenerator); ilGenerator.Emit(OperationCode.Ret); var ilMethodBody = new ILGeneratorMethodBody(ilGenerator, true, (ushort)((methodDefinition.ParameterCount + 1) * 2), methodDefinition, locals, new List <ITypeDefinition>()); methodDefinition.PlatformInvokeData = null; methodDefinition.Body = ilMethodBody; }
private static IMethodDefinition CreateFreeLibrary(IMetadataHost host, ITypeDefinition typeDef, IMethodReference windowsFreeLibrary, IMethodReference unixFreeLibrary, IFieldReference isUnix) { var methodDefinition = new MethodDefinition { Name = host.NameTable.GetNameFor("FreeLibrary"), ContainingTypeDefinition = typeDef, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr } }, IsStatic = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Public, Type = host.PlatformType.SystemInt32 }; var ilGenerator = new ILGenerator(host, methodDefinition); var label = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Ldsfld, isUnix); ilGenerator.Emit(OperationCode.Brtrue_S, label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Call, windowsFreeLibrary); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Call, unixFreeLibrary); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>()); return(methodDefinition); }
/// <summary> /// This method is called for all labels. /// </summary> /// <param name="op">The Microsoft intermediate language (MSIL) instruction that is marked as being a label.</param> /// <param name="label">A label that can be used to designate locations in MSIL where an instruction may jump.</param> protected virtual void RewriteLabel(IOperation op, ILGeneratorLabel label) { Contract.Requires(this.generator != null); Contract.Requires(op != null); Contract.Requires(label != null); this.generator.MarkLabel(label); }
private static IMethodDefinition CreateGetOperatingSystemMethod(IMetadataHost host, ITypeDefinition typeDef, IMethodReference stringOPEquality, IMethodReference uname) { var methodDefinition = new MethodDefinition { Name = host.NameTable.GetNameFor("GetOperatingSystem"), IsStatic = true, ContainingTypeDefinition = typeDef, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Private, Type = host.PlatformType.SystemInt32 }; ILGenerator ilGenerator = new ILGenerator(host, methodDefinition); ilGenerator.Emit(OperationCode.Call, uname); ilGenerator.Emit(OperationCode.Stloc_0); var linuxLabel = new ILGeneratorLabel(); var darwinLabel = new ILGeneratorLabel(); var freebsdLabel = new ILGeneratorLabel(); var netbsdLabel = new ILGeneratorLabel(); var unknownLabel = new ILGeneratorLabel(); AddOperatingSystemCase(ilGenerator, "Linux", stringOPEquality, linuxLabel); AddOperatingSystemCase(ilGenerator, "Darwin", stringOPEquality, darwinLabel); AddOperatingSystemCase(ilGenerator, "FreeBSD", stringOPEquality, freebsdLabel); AddOperatingSystemCase(ilGenerator, "NetBSD", stringOPEquality, netbsdLabel); ilGenerator.Emit(OperationCode.Br_S, unknownLabel); ilGenerator.MarkLabel(linuxLabel); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(darwinLabel); ilGenerator.Emit(OperationCode.Ldc_I4_2); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(freebsdLabel); ilGenerator.Emit(OperationCode.Ldc_I4_3); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(netbsdLabel); ilGenerator.Emit(OperationCode.Ldc_I4_4); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(unknownLabel); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, new List <ILocalDefinition> { new LocalDefinition { Type = host.PlatformType.SystemString } }, new List <ITypeDefinition>()); return(methodDefinition); }
private ILGeneratorLabel GetLabelFor(uint offset) { var result = this.labelFor[offset]; if (result == null) { this.labelFor[offset] = result = new ILGeneratorLabel(); } return(result); }
/// <summary> /// This method is called for all opcodes related to branches: /// OperationCode.Beq: /// OperationCode.Bge: /// OperationCode.Bge_Un: /// OperationCode.Bgt: /// OperationCode.Bgt_Un: /// OperationCode.Ble: /// OperationCode.Ble_Un: /// OperationCode.Blt: /// OperationCode.Blt_Un: /// OperationCode.Bne_Un: /// OperationCode.Br: /// OperationCode.Brfalse: /// OperationCode.Brtrue: /// OperationCode.Leave: /// OperationCode.Beq_S: /// OperationCode.Bge_S: /// OperationCode.Bge_Un_S: /// OperationCode.Bgt_S: /// OperationCode.Bgt_Un_S: /// OperationCode.Ble_S: /// OperationCode.Ble_Un_S: /// OperationCode.Blt_S: /// OperationCode.Blt_Un_S: /// OperationCode.Bne_Un_S: /// OperationCode.Br_S: /// OperationCode.Brfalse_S: /// OperationCode.Brtrue_S: /// OperationCode.Leave_S: /// </summary> /// <param name="op">The Microsoft intermediate language (MSIL) instruction to be copied.</param> protected virtual void RewriteBranch(IOperation op) { Contract.Requires(this.generator != null); Contract.Requires(op != null); // handle branches switch (op.OperationCode) { // Branches case OperationCode.Beq: case OperationCode.Bge: case OperationCode.Bge_Un: case OperationCode.Bgt: case OperationCode.Bgt_Un: case OperationCode.Ble: case OperationCode.Ble_Un: case OperationCode.Blt: case OperationCode.Blt_Un: case OperationCode.Bne_Un: case OperationCode.Br: case OperationCode.Brfalse: case OperationCode.Brtrue: case OperationCode.Leave: case OperationCode.Beq_S: case OperationCode.Bge_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_S: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un_S: case OperationCode.Br_S: case OperationCode.Brfalse_S: case OperationCode.Brtrue_S: case OperationCode.Leave_S: this.generator.Emit(ILGenerator.LongVersionOf(op.OperationCode), this.offset2Label[(uint)op.Value]); break; case OperationCode.Switch: uint[] offsets = op.Value as uint[]; ILGeneratorLabel[] labels = new ILGeneratorLabel[offsets.Length]; for (int j = 0, n = offsets.Length; j < n; j++) { labels[j] = offset2Label[offsets[j]]; } this.generator.Emit(OperationCode.Switch, labels); break; default: throw new Exception("Only branches should be handled here"); } }
private static void EmitBoolMarshalling(ILGenerator ilGenerator) { var trueCase = new ILGeneratorLabel(); var falseCase = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Brtrue_S, trueCase); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Br_S, falseCase); ilGenerator.MarkLabel(trueCase); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.MarkLabel(falseCase); }
private static void EmitUnicodeStringMarshalling(List <ILocalDefinition> locals, ILGenerator ilGenerator, IMethodReference getOffsetToStringData, ITypeReference stringType) { var pinnedLocal = new LocalDefinition { IsPinned = true, Type = stringType }; locals.Add(pinnedLocal); var nullCaseLabel = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Stloc, pinnedLocal); ilGenerator.Emit(OperationCode.Ldloc, pinnedLocal); ilGenerator.Emit(OperationCode.Conv_I); ilGenerator.Emit(OperationCode.Dup); ilGenerator.Emit(OperationCode.Brfalse_S, nullCaseLabel); ilGenerator.Emit(OperationCode.Call, getOffsetToStringData); ilGenerator.Emit(OperationCode.Add); ilGenerator.MarkLabel(nullCaseLabel); }
private void PostprocessNonBlittableArrayArguments(IMethodDefinition methodDefinition, List <ILocalDefinition> locals, Dictionary <IParameterDefinition, ILocalDefinition> paramToLocalMap, ILGenerator ilGenerator) { bool hasReturnValue = methodDefinition.Type != this.host.PlatformType.SystemVoid; if (IsAnyParameterNonBlittableArray(methodDefinition)) { var retLocal = new LocalDefinition { IsPinned = false, Type = methodDefinition.Type }; if (hasReturnValue) { locals.Add(retLocal); ilGenerator.Emit(OperationCode.Stloc, retLocal); } var exitLabel = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Leave, exitLabel); ilGenerator.BeginFinallyBlock(); foreach (var elem in methodDefinition.Parameters) { ILocalDefinition t; if (paramToLocalMap.TryGetValue(elem, out t)) { ilGenerator.Emit(OperationCode.Ldloc, t); ilGenerator.Emit(OperationCode.Call, this.stringArrayMarshallingEpilog); // TODO: Generalize for other array types } } ilGenerator.Emit(OperationCode.Endfinally); ilGenerator.EndTryBody(); ilGenerator.MarkLabel(exitLabel); if (hasReturnValue) { ilGenerator.Emit(OperationCode.Ldloc, retLocal); } } }
private static void EmitBlittableTypeArrayMarshalling(List <ILocalDefinition> locals, ILGenerator ilGenerator, IArrayType arrayType) { var nullCaseLabel = new ILGeneratorLabel(); // [0] T& pinned x var pinnedLocal = new LocalDefinition { IsPinned = true, IsReference = true, Type = arrayType.ElementType }; // [1] T[] V_1, var duplicatearray = new LocalDefinition { IsPinned = false, Type = arrayType }; locals.Add(pinnedLocal); locals.Add(duplicatearray); ilGenerator.Emit(OperationCode.Dup); ilGenerator.Emit(OperationCode.Stloc, duplicatearray); ilGenerator.Emit(OperationCode.Brfalse, nullCaseLabel); ilGenerator.Emit(OperationCode.Ldloc, duplicatearray); ilGenerator.Emit(OperationCode.Ldlen); ilGenerator.Emit(OperationCode.Conv_I4); ilGenerator.Emit(OperationCode.Brfalse, nullCaseLabel); ilGenerator.Emit(OperationCode.Ldloc, duplicatearray); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ldelema, arrayType.ElementType); ilGenerator.Emit(OperationCode.Stloc, pinnedLocal); ilGenerator.MarkLabel(nullCaseLabel); ilGenerator.Emit(OperationCode.Ldloc, pinnedLocal); ilGenerator.Emit(OperationCode.Conv_I); }
/// <summary> /// Emits the specified number of operations from the original method body. /// </summary> /// <param name="count"></param> public void EmitOperations(int count) { for (int i = 0; i < count; i++) { IOperation op = operations[0]; operations.RemoveAt(0); ILGeneratorLabel label; if (op.Location is IILLocation) { MarkSequencePoint(op.Location); } // Mark operation if it is a label for a branch if (offset2Label.TryGetValue(op.Offset, out label)) { MarkLabel(label); } // Mark operation if it is pointed to by an exception handler bool ignore; uint offset = op.Offset; if (offsetsUsedInExceptionInformation.TryGetValue(offset, out ignore)) { foreach (var exceptionInfo in methodBody.OperationExceptionInformation) { if (offset == exceptionInfo.TryStartOffset) { BeginTryBody(); } // Never need to do anthing when offset == exceptionInfo.TryEndOffset because // we pick up an EndTryBody from the HandlerEndOffset below // EndTryBody(); if (offset == exceptionInfo.HandlerStartOffset) { switch (exceptionInfo.HandlerKind) { case HandlerKind.Catch: BeginCatchBlock(exceptionInfo.ExceptionType); break; case HandlerKind.Fault: BeginFaultBlock(); break; case HandlerKind.Filter: BeginFilterBody(); break; case HandlerKind.Finally: BeginFinallyBlock(); break; } } if (exceptionInfo.HandlerKind == HandlerKind.Filter && offset == exceptionInfo.FilterDecisionStartOffset) { BeginFilterBlock(); } if (offset == exceptionInfo.HandlerEndOffset) { EndTryBody(); } } } // Emit operation along with any injection switch (op.OperationCode) { // Branches case OperationCode.Beq: case OperationCode.Bge: case OperationCode.Bge_Un: case OperationCode.Bgt: case OperationCode.Bgt_Un: case OperationCode.Ble: case OperationCode.Ble_Un: case OperationCode.Blt: case OperationCode.Blt_Un: case OperationCode.Bne_Un: case OperationCode.Br: case OperationCode.Brfalse: case OperationCode.Brtrue: case OperationCode.Leave: case OperationCode.Beq_S: case OperationCode.Bge_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_S: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un_S: case OperationCode.Br_S: case OperationCode.Brfalse_S: case OperationCode.Brtrue_S: case OperationCode.Leave_S: Emit(ILGenerator.LongVersionOf(op.OperationCode), offset2Label[(uint)op.Value]); break; case OperationCode.Switch: uint[] offsets = op.Value as uint[]; ILGeneratorLabel[] labels = new ILGeneratorLabel[offsets.Length]; for (int j = 0, n = offsets.Length; j < n; j++) { labels[j] = offset2Label[offsets[j]]; } Emit(OperationCode.Switch, labels); break; // Everything else default: if (op.Value == null) { Emit(op.OperationCode); break; } var typeCode = System.Convert.GetTypeCode(op.Value); switch (typeCode) { case TypeCode.Byte: Emit(op.OperationCode, (byte)op.Value); break; case TypeCode.Double: Emit(op.OperationCode, (double)op.Value); break; case TypeCode.Int16: Emit(op.OperationCode, (short)op.Value); break; case TypeCode.Int32: Emit(op.OperationCode, (int)op.Value); break; case TypeCode.Int64: Emit(op.OperationCode, (long)op.Value); break; case TypeCode.Object: IFieldReference fieldReference = op.Value as IFieldReference; if (fieldReference != null) { Emit(op.OperationCode, fieldReference); break; } ILocalDefinition localDefinition = op.Value as ILocalDefinition; if (localDefinition != null) { Emit(op.OperationCode, localDefinition); break; } IMethodReference methodReference = op.Value as IMethodReference; if (methodReference != null) { Emit(op.OperationCode, methodReference); break; } IParameterDefinition parameterDefinition = op.Value as IParameterDefinition; if (parameterDefinition != null) { Emit(op.OperationCode, parameterDefinition); break; } ISignature signature = op.Value as ISignature; if (signature != null) { Emit(op.OperationCode, signature); break; } ITypeReference typeReference = op.Value as ITypeReference; if (typeReference != null) { Emit(op.OperationCode, typeReference); break; } throw new Exception("Should never get here: no other IOperation argument types should exist"); case TypeCode.SByte: Emit(op.OperationCode, (sbyte)op.Value); break; case TypeCode.Single: Emit(op.OperationCode, (float)op.Value); break; case TypeCode.String: Emit(op.OperationCode, (string)op.Value); break; default: throw new Exception("Should never get here: no other IOperation argument types should exist"); } break; } } }
private static IMethodDefinition CreateStringArrayMarshallingProlog(IMetadataHost host, ITypeDefinition typeDef, IMethodReference stringToHGlobal, string methodName) { var stringArrayType = new VectorTypeReference { ElementType = host.PlatformType.SystemString, Rank = 1 }; var intPtrArrayType = new VectorTypeReference { ElementType = host.PlatformType.SystemIntPtr, Rank = 1 }; MethodDefinition methodDefinition = new MethodDefinition { ContainingTypeDefinition = typeDef, IsStatic = true, Visibility = TypeMemberVisibility.Assembly, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = stringArrayType }, new ParameterDefinition { Index = 1, Type = intPtrArrayType } }, Type = host.PlatformType.SystemVoid, Name = host.NameTable.GetNameFor(methodName) }; var size = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var index = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var locals = new List <ILocalDefinition> { size, index }; var ilGenerator = new ILGenerator(host, methodDefinition); var loopStart = new ILGeneratorLabel(); var loopBackEdge = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldlen); ilGenerator.Emit(OperationCode.Conv_I4); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Br_S, loopBackEdge); ilGenerator.MarkLabel(loopStart); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldelem_Ref); ilGenerator.Emit(OperationCode.Call, stringToHGlobal); ilGenerator.Emit(OperationCode.Stelem_I); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Add); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.MarkLabel(loopBackEdge); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Blt_S, loopStart); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 4, methodDefinition, locals, new List <ITypeDefinition>()); return(methodDefinition); }
private static IMethodDefinition CreateStringToAnsi(IMetadataHost host, ITypeDefinition typeDef, IMethodReference getLength, IMethodReference getChars) { var byteType = host.PlatformType.SystemUInt8; var byteArrayType = new VectorTypeReference { ElementType = byteType, Rank = 1 }; MethodDefinition methodDefinition = new MethodDefinition { ContainingTypeDefinition = typeDef, IsStatic = true, Visibility = TypeMemberVisibility.Assembly, Type = byteArrayType.ResolvedArrayType, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Type = host.PlatformType.SystemString } }, Name = host.NameTable.GetNameFor("StringToAnsiByteArray") }; var length = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var byteArray = new LocalDefinition { Type = byteArrayType.ResolvedArrayType }; var loopIndex = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var locals = new List <ILocalDefinition> { length, byteArray, loopIndex }; var ilGenerator = new ILGenerator(host, methodDefinition); var nullCaseLabel = new ILGeneratorLabel(); var loopStart = new ILGeneratorLabel(); var loopBackEdge = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Brtrue_S, nullCaseLabel); ilGenerator.Emit(OperationCode.Ldnull); ilGenerator.Emit(OperationCode.Ret); ilGenerator.MarkLabel(nullCaseLabel); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Call, getLength); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Add); ilGenerator.Emit(OperationCode.Newarr, byteArrayType); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Stloc_2); ilGenerator.Emit(OperationCode.Br_S, loopStart); ilGenerator.MarkLabel(loopBackEdge); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, getChars); ilGenerator.Emit(OperationCode.Conv_U1); ilGenerator.Emit(OperationCode.Stelem_I1); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Add); ilGenerator.Emit(OperationCode.Stloc_2); ilGenerator.MarkLabel(loopStart); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Blt_S, loopBackEdge); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Stelem_I1); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, locals, new List <ITypeDefinition>()); return(methodDefinition); }
private void InstrumentBlock(BasicBlock <Instruction> block) { var blockOffset = block.Instructions[0].Operation.Offset; this.ilGenerator.MarkLabel(this.GetLabelFor(blockOffset)); for (int i = 0, n = block.Instructions.Count - 1; i < n; i++) { var operation = block.Instructions[i].Operation; this.EmitDebugInformationFor(operation); this.ilGenerator.Emit(operation.OperationCode, operation.Value); } var lastOperation = block.Instructions[block.Instructions.Count - 1].Operation; this.EmitDebugInformationFor(lastOperation); switch (lastOperation.OperationCode) { case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: var unconditionalBranch = new ILGeneratorLabel(); var fallThrough = new ILGeneratorLabel(); this.ilGenerator.Emit(lastOperation.OperationCode, unconditionalBranch); this.ilGenerator.Emit(OperationCode.Br_S, fallThrough); this.ilGenerator.MarkLabel(unconditionalBranch); this.EmitCounterIncrement(lastOperation.Offset); this.ilGenerator.Emit(OperationCode.Br, this.GetLabelFor((uint)lastOperation.Value)); this.ilGenerator.MarkLabel(fallThrough); this.EmitCounterIncrement(lastOperation.Offset + 1); break; case OperationCode.Br: case OperationCode.Br_S: this.EmitCounterIncrement(lastOperation.Offset); this.ilGenerator.Emit(OperationCode.Br, this.GetLabelFor((uint)lastOperation.Value)); break; case OperationCode.Leave: case OperationCode.Leave_S: this.EmitCounterIncrement(lastOperation.Offset); this.ilGenerator.Emit(OperationCode.Leave, this.GetLabelFor((uint)lastOperation.Value)); break; case OperationCode.Endfilter: case OperationCode.Endfinally: case OperationCode.Jmp: case OperationCode.Ret: case OperationCode.Rethrow: case OperationCode.Throw: //No need to count the outgoing edge. Its count is the same as the number of times this block executes. this.ilGenerator.Emit(lastOperation.OperationCode, lastOperation.Value); break; case OperationCode.Switch: fallThrough = new ILGeneratorLabel(); uint[] targets = (uint[])lastOperation.Value; ILGeneratorLabel[] counters = new ILGeneratorLabel[targets.Length]; for (int i = 0, n = counters.Length; i < n; i++) { counters[i] = new ILGeneratorLabel(); } this.ilGenerator.Emit(OperationCode.Switch, counters); this.EmitCounterIncrement(lastOperation.Offset); this.ilGenerator.Emit(OperationCode.Br, fallThrough); for (int i = 0, n = counters.Length; i < n; i++) { var counterLabel = counters[i]; this.ilGenerator.MarkLabel(counterLabel); this.EmitCounterIncrement(lastOperation.Offset + 1 + (uint)i); this.ilGenerator.Emit(OperationCode.Br, this.GetLabelFor(targets[i])); } this.ilGenerator.MarkLabel(fallThrough); break; default: this.ilGenerator.Emit(lastOperation.OperationCode, lastOperation.Value); this.EmitCounterIncrement(lastOperation.Offset); break; } }
private static IMethodDefinition CreateStringArrayMarshallingEpilog(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero, IMethodReference intPtrOpInequality, IMethodReference freeHGlobal) { var intPtrArrayType = new VectorTypeReference { ElementType = host.PlatformType.SystemIntPtr, Rank = 1 }; MethodDefinition methodDefinition = new MethodDefinition { ContainingTypeDefinition = typeDef, IsStatic = true, Visibility = TypeMemberVisibility.Assembly, Type = host.PlatformType.SystemVoid, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = intPtrArrayType } }, Name = host.NameTable.GetNameFor("StringArrayMarshallingEpilog") }; var size = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var index = new LocalDefinition { Type = host.PlatformType.SystemInt32 }; var locals = new List <ILocalDefinition> { size, index }; var ilGenerator = new ILGenerator(host, methodDefinition); var loopStart = new ILGeneratorLabel(); var loopBackEdge = new ILGeneratorLabel(); var exitLabel = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldlen); ilGenerator.Emit(OperationCode.Conv_I4); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Br_S, loopBackEdge); ilGenerator.MarkLabel(loopStart); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldelem_I); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpInequality); ilGenerator.Emit(OperationCode.Brfalse_S, exitLabel); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldelem_I); ilGenerator.Emit(OperationCode.Call, freeHGlobal); ilGenerator.MarkLabel(exitLabel); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Add); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.MarkLabel(loopBackEdge); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Blt_S, loopStart); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, locals, new List <ITypeDefinition>()); return(methodDefinition); }
private static IMethodDefinition CreateDLMethod(IMetadataHost host, ITypeDefinition typeDef, IName name, List <IParameterDefinition> parameters, ITypeReference returnType, IMethodReference getOperatingSystem, IMethodReference linuxHelpers, IMethodReference darwinHelpers, IMethodReference bsdHelpers, bool generateSecondLoad = true) { var methodDefinition = new MethodDefinition { Name = name, Parameters = parameters, ContainingTypeDefinition = typeDef, IsStatic = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Public, Type = returnType }; var labels = new ILGeneratorLabel[4]; var linuxLabel = new ILGeneratorLabel(); var darwinLabel = new ILGeneratorLabel(); var bsdLabel = new ILGeneratorLabel(); var unknownLabel = new ILGeneratorLabel(); labels[0] = linuxLabel; labels[1] = darwinLabel; labels[2] = bsdLabel; labels[3] = bsdLabel; var ilGenerator = new ILGenerator(host, methodDefinition); ilGenerator.Emit(OperationCode.Call, getOperatingSystem); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldc_I4_1); ilGenerator.Emit(OperationCode.Sub); ilGenerator.Emit(OperationCode.Switch, labels); ilGenerator.Emit(OperationCode.Br_S, unknownLabel); AddOperatingSystemCase2(ilGenerator, linuxHelpers, linuxLabel, generateSecondLoad); AddOperatingSystemCase2(ilGenerator, darwinHelpers, darwinLabel, generateSecondLoad); AddOperatingSystemCase2(ilGenerator, bsdHelpers, bsdLabel, generateSecondLoad); ilGenerator.MarkLabel(unknownLabel); ilGenerator.Emit(OperationCode.Ldstr, "Platform Not Supported"); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, new List <ILocalDefinition> { new LocalDefinition { Type = host.PlatformType.SystemInt32 } }, new List <ITypeDefinition>()); return(methodDefinition); }
private static void AddOperatingSystemCase2(ILGenerator ilGenerator, IMethodReference helper, ILGeneratorLabel label, bool generateSecondLoad = true) { ilGenerator.MarkLabel(label); ilGenerator.Emit(OperationCode.Ldarg_0); if (generateSecondLoad) { ilGenerator.Emit(OperationCode.Ldarg_1); } ilGenerator.Emit(OperationCode.Call, helper); ilGenerator.Emit(OperationCode.Ret); }
private static void AddOperatingSystemCase(ILGenerator ilGenerator, string operatingSystemName, IMethodReference stringOPEquality, ILGeneratorLabel operatingSystemSwitchLabel) { ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, operatingSystemName); ilGenerator.Emit(OperationCode.Call, stringOPEquality); ilGenerator.Emit(OperationCode.Brtrue_S, operatingSystemSwitchLabel); }
private static IMethodDefinition CreateUnameMethod(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero, IMethodReference allocHGlobal, IMethodReference ptrToStringAnsi, IMethodReference freeHGlobal, IMethodReference unamePInvoke, IMethodReference intPtrOpInequality) { var methodDefinition = new MethodDefinition { Name = host.NameTable.GetNameFor("uname"), IsStatic = true, IsHiddenBySignature = true, ContainingTypeDefinition = typeDef, Visibility = TypeMemberVisibility.Private, Type = host.PlatformType.SystemString }; var ilGenerator = new ILGenerator(host, methodDefinition); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.BeginTryBody(); ilGenerator.Emit(OperationCode.Ldc_I4, 4096); ilGenerator.Emit(OperationCode.Call, allocHGlobal); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Call, unamePInvoke); var emptyStringLabel = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Brtrue_S, emptyStringLabel); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Call, ptrToStringAnsi); ilGenerator.Emit(OperationCode.Stloc_1); var exitLabel = new ILGeneratorLabel(); var endFinallyLabel = new ILGeneratorLabel(); ilGenerator.Emit(OperationCode.Leave_S, exitLabel); ilGenerator.MarkLabel(emptyStringLabel); ilGenerator.Emit(OperationCode.Ldstr, ""); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Leave_S, exitLabel); ilGenerator.BeginFinallyBlock(); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpInequality); ilGenerator.Emit(OperationCode.Brfalse_S, endFinallyLabel); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Call, freeHGlobal); ilGenerator.MarkLabel(endFinallyLabel); ilGenerator.Emit(OperationCode.Endfinally); ilGenerator.EndTryBody(); ilGenerator.MarkLabel(exitLabel); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, new List <ILocalDefinition> { new LocalDefinition { Type = host.PlatformType.SystemIntPtr }, new LocalDefinition { Type = host.PlatformType.SystemString } }, new List <ITypeDefinition>()); return(methodDefinition); }
private static IMethodDefinition CreateIsLibraryInitialized(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero) { MethodDefinition methodDefinition = new MethodDefinition { ContainingTypeDefinition = typeDef, IsStatic = true, IsNeverInlined = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Assembly, Type = host.PlatformType.SystemVoid, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } }, Name = host.NameTable.GetNameFor("IsLibraryInitialized") }; var ilGenerator = new ILGenerator(host, methodDefinition); var retLabel = new ILGeneratorLabel(); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("Concat"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemString, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 2, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 3, Type = host.PlatformType.SystemString } } }; var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpEquality); ilGenerator.Emit(OperationCode.Brfalse_S, retLabel); ilGenerator.Emit(OperationCode.Ldstr, "Library '"); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Ldstr, "' is not initialized. Load the native library (from its file path) by calling LoadLibrary"); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, stringConcat); ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>()); return(methodDefinition); }
private static IMethodDefinition CreateGetProcAddress(IMetadataHost host, ITypeDefinition typeDef, IMethodReference windowsGetProcAddress, IMethodReference unixGetProcAddress, IFieldReference isUnix, IFieldReference intPtrZero) { var methodDefinition = new MethodDefinition { Name = host.NameTable.GetNameFor("GetProcAddress"), ContainingTypeDefinition = typeDef, Parameters = new List <IParameterDefinition> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } }, IsStatic = true, IsHiddenBySignature = true, Visibility = TypeMemberVisibility.Public, Type = host.PlatformType.SystemIntPtr }; var ilGenerator = new ILGenerator(host, methodDefinition); var label = new ILGeneratorLabel(); var retLabel = new ILGeneratorLabel(); var dupLabel = new ILGeneratorLabel(); var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor(".ctor"), ContainingType = host.PlatformType.SystemException, Type = host.PlatformType.SystemVoid, CallingConvention = CallingConvention.HasThis, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString } } }; var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.GetNameFor("Concat"), ContainingType = host.PlatformType.SystemString, Type = host.PlatformType.SystemString, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemString }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemString } } }; var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference { Name = host.NameTable.OpEquality, ContainingType = host.PlatformType.SystemIntPtr, Type = host.PlatformType.SystemBoolean, Parameters = new List <IParameterTypeInformation> { new ParameterDefinition { Index = 0, Type = host.PlatformType.SystemIntPtr }, new ParameterDefinition { Index = 1, Type = host.PlatformType.SystemIntPtr } } }; ilGenerator.Emit(OperationCode.Ldsfld, isUnix); ilGenerator.Emit(OperationCode.Brtrue_S, label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, windowsGetProcAddress); ilGenerator.Emit(OperationCode.Br_S, dupLabel); ilGenerator.MarkLabel(label); ilGenerator.Emit(OperationCode.Ldarg_0); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, unixGetProcAddress); ilGenerator.MarkLabel(dupLabel); ilGenerator.Emit(OperationCode.Dup); ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero); ilGenerator.Emit(OperationCode.Call, intPtrOpEquality); ilGenerator.Emit(OperationCode.Brfalse_S, retLabel); ilGenerator.Emit(OperationCode.Ldstr, "GetProcAddress failed for: "); ilGenerator.Emit(OperationCode.Ldarg_1); ilGenerator.Emit(OperationCode.Call, stringConcat); ilGenerator.Emit(OperationCode.Newobj, exceptionCtor); ilGenerator.Emit(OperationCode.Throw); ilGenerator.MarkLabel(retLabel); ilGenerator.Emit(OperationCode.Ret); methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>()); return(methodDefinition); }
[ContractVerification(false)] //Times out private void Inline(IMethodBody methodBody) { Contract.Requires(methodBody != null); var savedCombinedMaxStack = this.combinedMaxStack; this.combinedMaxStack += methodBody.MaxStack; if (this.combinedMaxStack > this.maxStack) this.maxStack = this.combinedMaxStack; var savedLocalForThis = this.localForThis; var nametable = this.Host.NameTable; var method = methodBody.MethodDefinition; var n = method.ParameterCount; if (!method.IsStatic) n++; var temps = new GeneratorLocal[n]; for (ushort i = 0; i < n; i++) temps[i] = new GeneratorLocal() { MethodDefinition = method }; var j = 0; if (!method.IsStatic) { var temp0 = temps[0]; Contract.Assume(temp0 != null); temp0.Name = nametable.GetNameFor("this"); temp0.Type = method.ContainingTypeDefinition; if (method.ContainingTypeDefinition.IsValueType) temp0.Type = ManagedPointerType.GetManagedPointerType(temp0.Type, this.Host.InternFactory); j = 1; this.localForThis = temp0; } foreach (var par in methodBody.MethodDefinition.Parameters) { Contract.Assume(par != null); Contract.Assume(j < n); var tempj = temps[j++]; Contract.Assume(tempj != null); this.localFor[par] = tempj; tempj.Name = par.Name; tempj.Type = par.Type; if (par.IsByReference) tempj.Type = ManagedPointerType.GetManagedPointerType(tempj.Type, this.Host.InternFactory); } this.Generator.BeginScope(); for (int i = n-1; i >= 0; i--) { var temp = temps[i]; Contract.Assume(temp != null); this.Generator.Emit(OperationCode.Stloc, temp); this.TrackLocal(temp); this.Generator.AddVariableToCurrentScope(temp); } var savedReturnLabel = this.returnLabel; var returnLabel = this.returnLabel = new ILGeneratorLabel(); this.EmitMethodBody(methodBody); this.Generator.MarkLabel(returnLabel); this.returnLabel = savedReturnLabel; this.localForThis = savedLocalForThis; this.Generator.EndScope(); this.combinedMaxStack = savedCombinedMaxStack; }
public void Compile(string fileName) { string appName = Path.GetFileNameWithoutExtension(fileName); string exeName = appName + ".exe"; string src = ""; using (TextReader file = new StreamReader(fileName)) { src = file.ReadToEnd(); } var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { // Load Mirage types IModule module = host.LoadUnitFrom("Mirage.dll") as IModule; if (module == null || module is Dummy) { return; } var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine"); var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput"); var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput"); // Create assembly var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor(appName), ModuleName = nameTable.GetNameFor(exeName), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); // Create namespace var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; // Create module class var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); // Create program class var programClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Program"), }; programClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; rootUnitNamespace.Members.Add(programClass); // Add types to the assembly assembly.AllTypes.Add(machineType); foreach (var t in machineType.NestedTypes) { assembly.AllTypes.Add(t); } assembly.AllTypes.Add(inputType); assembly.AllTypes.Add(outputType); assembly.AllTypes.Add(programClass); // Create main method var mainMethod = new MethodDefinition() { ContainingTypeDefinition = programClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; programClass.Methods.Add(mainMethod); // Create constructors and methods IMethodReference machineConstructor = new Microsoft.Cci.MethodReference( host, machineType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); IMethodReference inputConstructor = new Microsoft.Cci.MethodReference( host, inputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType); IMethodReference outputConstructor = new Microsoft.Cci.MethodReference( host, outputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType); var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers")); var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers")); var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer")); var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer")); var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer")); var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer")); var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer")); var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers")); var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear")); var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add")); var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec")); var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not")); var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And")); var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or")); var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor")); var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal")); var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar")); var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString); var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type); var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type); var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz")); // Create program code var labels = new Stack <ILGeneratorLabel>(100); var ilGenerator = new ILGenerator(host, mainMethod); ilGenerator.Emit(OperationCode.Newobj, machineConstructor); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Newobj, inputConstructor); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Newobj, outputConstructor); ilGenerator.Emit(OperationCode.Stloc_2); int pc = 0; while (pc < src.Length) { char opcode = src[pc++]; switch (opcode) { case '>': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncPointers); break; case '<': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecPointers); break; case ']': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer); break; case '[': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer); break; case '#': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer); break; case '$': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer); break; case '=': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer); break; case '%': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXchPointers); break; case '_': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opClear); break; case '+': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAdd); break; case '-': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDec); break; case '~': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opNot); break; case '&': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAnd); break; case '|': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opOr); break; case '^': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXor); break; case '*': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSal); break; case '/': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSar); break; case '(': int dataStart = pc; int dataEnd = dataStart; while (src[pc++] != ')') { dataEnd = pc; } ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart)); ilGenerator.Emit(OperationCode.Callvirt, opLoadData); break; case '?': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Call, inputCast); ilGenerator.Emit(OperationCode.Callvirt, opInput); break; case '!': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, outputCast); ilGenerator.Emit(OperationCode.Callvirt, opOutput); break; case '{': var cycleStart = new ILGeneratorLabel(); var cycleEnd = new ILGeneratorLabel(); labels.Push(cycleStart); labels.Push(cycleEnd); ilGenerator.Emit(OperationCode.Br, cycleEnd); ilGenerator.MarkLabel(cycleStart); break; case '}': ilGenerator.MarkLabel(labels.Pop()); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opJz); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ceq); ilGenerator.Emit(OperationCode.Stloc_3); ilGenerator.Emit(OperationCode.Ldloc_3); ilGenerator.Emit(OperationCode.Brtrue, labels.Pop()); break; default: break; } } ilGenerator.Emit(OperationCode.Ret); mainMethod.Body = new ILGeneratorMethodBody( ilGenerator, true, 8, mainMethod, new List <ILocalDefinition>() { new LocalDefinition() { Type = machineType }, new LocalDefinition() { Type = inputType }, new LocalDefinition() { Type = outputType }, new LocalDefinition() { Type = host.PlatformType.SystemInt32 }, }, Enumerable <ITypeDefinition> .Empty ); using (var peStream = File.Create(exeName)) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
// makes a copy of the method public void copyMethod(MethodDefinition dest, IMethodDefinition source) { // only copy body if it is not a dummy (= empty) if (!(source.Body is Microsoft.Cci.Dummy)) { // copy instructions ILGenerator ilGenerator = new ILGenerator(this.host, dest); foreach (var operation in source.Body.Operations) { ilGenerator.Emit(operation.OperationCode, operation.Value); } // copy the exception handler foreach (IOperationExceptionInformation exceptionToCopy in source.Body.OperationExceptionInformation) { ILGeneratorLabel tryStart = new ILGeneratorLabel(); tryStart.Offset = exceptionToCopy.TryStartOffset; ILGeneratorLabel tryEnd = new ILGeneratorLabel(); tryEnd.Offset = exceptionToCopy.TryEndOffset; ILGeneratorLabel handlerStart = new ILGeneratorLabel(); handlerStart.Offset = exceptionToCopy.HandlerStartOffset; ILGeneratorLabel handlerEnd = new ILGeneratorLabel(); handlerEnd.Offset = exceptionToCopy.HandlerEndOffset; ILGeneratorLabel filterStart = new ILGeneratorLabel(); filterStart.Offset = exceptionToCopy.FilterDecisionStartOffset; ilGenerator.AddExceptionHandlerInformation(exceptionToCopy.HandlerKind, exceptionToCopy.ExceptionType, tryStart, tryEnd, handlerStart, handlerEnd, filterStart); } // create the body List <ILocalDefinition> variableListCopy = new List <ILocalDefinition>(source.Body.LocalVariables); List <ITypeDefinition> privateHelperTypesListCopy = new List <ITypeDefinition>(source.Body.PrivateHelperTypes); var newBody = new ILGeneratorMethodBody(ilGenerator, source.Body.LocalsAreZeroed, source.Body.MaxStack, dest, variableListCopy, privateHelperTypesListCopy); dest.Body = newBody; } dest.CallingConvention = source.CallingConvention; if (source.IsGeneric) { dest.GenericParameters = new List <IGenericMethodParameter>(source.GenericParameters); } else { dest.GenericParameters = null; } if (source.ParameterCount > 0) { dest.Parameters = new List <IParameterDefinition>(source.Parameters); } else { dest.Parameters = null; } if (source.IsPlatformInvoke) { dest.PlatformInvokeData = source.PlatformInvokeData; } else { dest.PlatformInvokeData = Dummy.PlatformInvokeInformation; } dest.ReturnValueAttributes = new List <ICustomAttribute>(source.ReturnValueAttributes); if (source.ReturnValueIsModified) { dest.ReturnValueCustomModifiers = new List <ICustomModifier>(source.ReturnValueCustomModifiers); } else { dest.ReturnValueCustomModifiers = new List <ICustomModifier>(0); } if (source.ReturnValueIsMarshalledExplicitly) { dest.ReturnValueMarshallingInformation = source.ReturnValueMarshallingInformation; } else { dest.ReturnValueMarshallingInformation = Dummy.MarshallingInformation; } if (source.HasDeclarativeSecurity && IteratorHelper.EnumerableIsNotEmpty(source.SecurityAttributes)) { dest.SecurityAttributes = new List <ISecurityAttribute>(source.SecurityAttributes); } else { dest.SecurityAttributes = null; } dest.Type = source.Type; dest.AcceptsExtraArguments = source.AcceptsExtraArguments; dest.HasDeclarativeSecurity = source.HasDeclarativeSecurity; dest.IsAbstract = source.IsAbstract; dest.IsAccessCheckedOnOverride = source.IsAccessCheckedOnOverride; dest.IsCil = source.IsCil; dest.IsExternal = source.IsExternal; dest.IsForwardReference = source.IsForwardReference; dest.IsHiddenBySignature = source.IsHiddenBySignature; dest.IsNativeCode = source.IsNativeCode; dest.IsNewSlot = source.IsNewSlot; dest.IsNeverInlined = source.IsNeverInlined; dest.IsAggressivelyInlined = source.IsAggressivelyInlined; dest.IsNeverOptimized = source.IsNeverOptimized; dest.IsPlatformInvoke = source.IsPlatformInvoke; dest.IsRuntimeImplemented = source.IsRuntimeImplemented; dest.IsRuntimeInternal = source.IsRuntimeInternal; dest.IsRuntimeSpecial = source.IsRuntimeSpecial; dest.IsSealed = source.IsSealed; dest.IsSpecialName = source.IsSpecialName; dest.IsStatic = source.IsStatic; dest.IsSynchronized = source.IsSynchronized; dest.IsUnmanaged = source.IsUnmanaged; if (dest.IsStatic) { dest.IsVirtual = false; } else { dest.IsVirtual = source.IsVirtual; } dest.PreserveSignature = source.PreserveSignature; dest.RequiresSecurityObject = source.RequiresSecurityObject; dest.ReturnValueIsByRef = source.ReturnValueIsByRef; dest.ReturnValueIsMarshalledExplicitly = source.ReturnValueIsMarshalledExplicitly; dest.ReturnValueName = source.ReturnValueName; dest.Name = source.Name; dest.Visibility = source.Visibility; }
[ContractVerification(false)] //Times out private void Inline(IMethodBody methodBody) { Contract.Requires(methodBody != null); var savedCombinedMaxStack = this.combinedMaxStack; this.combinedMaxStack += methodBody.MaxStack; if (this.combinedMaxStack > this.maxStack) { this.maxStack = this.combinedMaxStack; } var savedLocalForThis = this.localForThis; var nametable = this.Host.NameTable; var method = methodBody.MethodDefinition; var n = method.ParameterCount; if (!method.IsStatic) { n++; } var temps = new GeneratorLocal[n]; for (ushort i = 0; i < n; i++) { temps[i] = new GeneratorLocal() { MethodDefinition = method } } ; var j = 0; if (!method.IsStatic) { var temp0 = temps[0]; Contract.Assume(temp0 != null); temp0.Name = nametable.GetNameFor("this"); temp0.Type = method.ContainingTypeDefinition; if (method.ContainingTypeDefinition.IsValueType) { temp0.Type = ManagedPointerType.GetManagedPointerType(temp0.Type, this.Host.InternFactory); } j = 1; this.localForThis = temp0; } foreach (var par in methodBody.MethodDefinition.Parameters) { Contract.Assume(par != null); Contract.Assume(j < n); var tempj = temps[j++]; Contract.Assume(tempj != null); this.localFor[par] = tempj; tempj.Name = par.Name; tempj.Type = par.Type; if (par.IsByReference) { tempj.Type = ManagedPointerType.GetManagedPointerType(tempj.Type, this.Host.InternFactory); } } this.Generator.BeginScope(); for (int i = n - 1; i >= 0; i--) { var temp = temps[i]; Contract.Assume(temp != null); this.Generator.Emit(OperationCode.Stloc, temp); this.TrackLocal(temp); this.Generator.AddVariableToCurrentScope(temp); } var savedReturnLabel = this.returnLabel; var returnLabel = this.returnLabel = new ILGeneratorLabel(); this.EmitMethodBody(methodBody); this.Generator.MarkLabel(returnLabel); this.returnLabel = savedReturnLabel; this.localForThis = savedLocalForThis; this.Generator.EndScope(); this.combinedMaxStack = savedCombinedMaxStack; } }
private void ProcessOperations(IMethodBody methodBody) { List <IOperation> operations = ((methodBody.Operations == null) ? new List <IOperation>(): new List <IOperation>(methodBody.Operations)); int count = operations.Count; ILGenerator generator = new ILGenerator(this.host, methodBody.MethodDefinition); if (this.pdbReader != null) { foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody)) { foreach (var uns in ns.UsedNamespaces) { generator.UseNamespace(uns.NamespaceName.Value); } } } this.currentGenerator = generator; this.scopeEnumerator = this.pdbReader == null ? null : this.pdbReader.GetLocalScopes(methodBody).GetEnumerator(); this.scopeEnumeratorIsValid = this.scopeEnumerator != null && this.scopeEnumerator.MoveNext(); var methodName = MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.SmartTypeName); #region Record all offsets that appear as part of an exception handler Dictionary <uint, bool> offsetsUsedInExceptionInformation = new Dictionary <uint, bool>(); foreach (var exceptionInfo in methodBody.OperationExceptionInformation ?? Enumerable <IOperationExceptionInformation> .Empty) { uint x = exceptionInfo.TryStartOffset; if (!offsetsUsedInExceptionInformation.ContainsKey(x)) { offsetsUsedInExceptionInformation.Add(x, true); } x = exceptionInfo.TryEndOffset; if (!offsetsUsedInExceptionInformation.ContainsKey(x)) { offsetsUsedInExceptionInformation.Add(x, true); } x = exceptionInfo.HandlerStartOffset; if (!offsetsUsedInExceptionInformation.ContainsKey(x)) { offsetsUsedInExceptionInformation.Add(x, true); } x = exceptionInfo.HandlerEndOffset; if (!offsetsUsedInExceptionInformation.ContainsKey(x)) { offsetsUsedInExceptionInformation.Add(x, true); } if (exceptionInfo.HandlerKind == HandlerKind.Filter) { x = exceptionInfo.FilterDecisionStartOffset; if (!offsetsUsedInExceptionInformation.ContainsKey(x)) { offsetsUsedInExceptionInformation.Add(x, true); } } } #endregion Record all offsets that appear as part of an exception handler Dictionary <uint, ILGeneratorLabel> offset2Label = new Dictionary <uint, ILGeneratorLabel>(); #region Pass 1: Make a label for each branch target for (int i = 0; i < count; i++) { IOperation op = operations[i]; switch (op.OperationCode) { case OperationCode.Beq: case OperationCode.Bge: case OperationCode.Bge_Un: case OperationCode.Bgt: case OperationCode.Bgt_Un: case OperationCode.Ble: case OperationCode.Ble_Un: case OperationCode.Blt: case OperationCode.Blt_Un: case OperationCode.Bne_Un: case OperationCode.Br: case OperationCode.Brfalse: case OperationCode.Brtrue: case OperationCode.Leave: case OperationCode.Beq_S: case OperationCode.Bge_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_S: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un_S: case OperationCode.Br_S: case OperationCode.Brfalse_S: case OperationCode.Brtrue_S: case OperationCode.Leave_S: uint x = (uint)op.Value; if (!offset2Label.ContainsKey(x)) { offset2Label.Add(x, new ILGeneratorLabel()); } break; case OperationCode.Switch: uint[] offsets = op.Value as uint[]; foreach (var offset in offsets) { if (!offset2Label.ContainsKey(offset)) { offset2Label.Add(offset, new ILGeneratorLabel()); } } break; default: break; } } #endregion Pass 1: Make a label for each branch target #region Pass 2: Emit each operation, along with labels for (int i = 0; i < count; i++) { IOperation op = operations[i]; ILGeneratorLabel label; this.EmitDebugInformationFor(op); #region Mark operation if it is a label for a branch if (offset2Label.TryGetValue(op.Offset, out label)) { generator.MarkLabel(label); } #endregion Mark operation if it is a label for a branch #region Mark operation if it is pointed to by an exception handler bool ignore; uint offset = op.Offset; if (offsetsUsedInExceptionInformation.TryGetValue(offset, out ignore)) { foreach (var exceptionInfo in methodBody.OperationExceptionInformation) { if (offset == exceptionInfo.TryStartOffset) { generator.BeginTryBody(); } // Never need to do anthing when offset == exceptionInfo.TryEndOffset because // we pick up an EndTryBody from the HandlerEndOffset below // generator.EndTryBody(); if (offset == exceptionInfo.HandlerStartOffset) { switch (exceptionInfo.HandlerKind) { case HandlerKind.Catch: generator.BeginCatchBlock(exceptionInfo.ExceptionType); break; case HandlerKind.Fault: generator.BeginFaultBlock(); break; case HandlerKind.Filter: generator.BeginFilterBody(); break; case HandlerKind.Finally: generator.BeginFinallyBlock(); break; } } if (exceptionInfo.HandlerKind == HandlerKind.Filter && offset == exceptionInfo.FilterDecisionStartOffset) { generator.BeginFilterBlock(); } if (offset == exceptionInfo.HandlerEndOffset) { generator.EndTryBody(); } } } #endregion Mark operation if it is pointed to by an exception handler #region Emit operation along with any injection switch (op.OperationCode) { #region Branches case OperationCode.Beq: case OperationCode.Bge: case OperationCode.Bge_Un: case OperationCode.Bgt: case OperationCode.Bgt_Un: case OperationCode.Ble: case OperationCode.Ble_Un: case OperationCode.Blt: case OperationCode.Blt_Un: case OperationCode.Bne_Un: case OperationCode.Br: case OperationCode.Brfalse: case OperationCode.Brtrue: case OperationCode.Leave: case OperationCode.Beq_S: case OperationCode.Bge_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_S: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un_S: case OperationCode.Br_S: case OperationCode.Brfalse_S: case OperationCode.Brtrue_S: case OperationCode.Leave_S: generator.Emit(ILGenerator.LongVersionOf(op.OperationCode), offset2Label[(uint)op.Value]); break; case OperationCode.Switch: uint[] offsets = op.Value as uint[]; ILGeneratorLabel[] labels = new ILGeneratorLabel[offsets.Length]; for (int j = 0, n = offsets.Length; j < n; j++) { labels[j] = offset2Label[offsets[j]]; } generator.Emit(OperationCode.Switch, labels); break; #endregion Branches #region Everything else case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: generator.Emit(op.OperationCode); EmitStoreLocal(generator, op); break; case OperationCode.Stloc: case OperationCode.Stloc_S: generator.Emit(op.OperationCode, op.Value); EmitStoreLocal(generator, op); break; default: if (op.Value == null) { generator.Emit(op.OperationCode); break; } var typeCode = System.Convert.GetTypeCode(op.Value); switch (typeCode) { case TypeCode.Byte: generator.Emit(op.OperationCode, (byte)op.Value); break; case TypeCode.Double: generator.Emit(op.OperationCode, (double)op.Value); break; case TypeCode.Int16: generator.Emit(op.OperationCode, (short)op.Value); break; case TypeCode.Int32: generator.Emit(op.OperationCode, (int)op.Value); break; case TypeCode.Int64: generator.Emit(op.OperationCode, (long)op.Value); break; case TypeCode.Object: IFieldReference fieldReference = op.Value as IFieldReference; if (fieldReference != null) { generator.Emit(op.OperationCode, this.Rewrite(fieldReference)); break; } ILocalDefinition localDefinition = op.Value as ILocalDefinition; if (localDefinition != null) { generator.Emit(op.OperationCode, localDefinition); break; } IMethodReference methodReference = op.Value as IMethodReference; if (methodReference != null) { generator.Emit(op.OperationCode, this.Rewrite(methodReference)); break; } IParameterDefinition parameterDefinition = op.Value as IParameterDefinition; if (parameterDefinition != null) { generator.Emit(op.OperationCode, parameterDefinition); break; } ISignature signature = op.Value as ISignature; if (signature != null) { generator.Emit(op.OperationCode, signature); break; } ITypeReference typeReference = op.Value as ITypeReference; if (typeReference != null) { generator.Emit(op.OperationCode, this.Rewrite(typeReference)); break; } throw new ILMutatorException("Should never get here: no other IOperation argument types should exist"); case TypeCode.SByte: generator.Emit(op.OperationCode, (sbyte)op.Value); break; case TypeCode.Single: generator.Emit(op.OperationCode, (float)op.Value); break; case TypeCode.String: generator.Emit(op.OperationCode, (string)op.Value); break; default: // The other cases are the other enum values that TypeCode has. // But no other argument types should be in the Operations. ILGenerator cannot handle anything else, // so such IOperations should never exist. //case TypeCode.Boolean: //case TypeCode.Char: //case TypeCode.DateTime: //case TypeCode.DBNull: //case TypeCode.Decimal: //case TypeCode.Empty: // this would be the value for null, but the case when op.Value is null is handled before the switch statement //case TypeCode.UInt16: //case TypeCode.UInt32: //case TypeCode.UInt64: throw new ILMutatorException("Should never get here: no other IOperation argument types should exist"); } break; #endregion Everything else } #endregion Emit operation along with any injection } while (generator.InTryBody) { generator.EndTryBody(); } while (this.scopeStack.Count > 0) { this.currentGenerator.EndScope(); this.scopeStack.Pop(); } #endregion Pass 2: Emit each operation, along with labels }