public Label DefineLabel() { if (il == null) il = builder.GetILGenerator(); return il.DefineLabel(); }
public void Emit_UnknownOpCode_ThrowsNotSupportedException() { var ilGenerator = new ILGenerator(null); var opCode = new OpCode(-1); ExceptionAssert.Throws<NotSupportedException>(() => ilGenerator.Emit(opCode)); }
public LocalBuilder AddLocal(IKType type) { if (il == null) il = builder.GetILGenerator(); return il.DeclareLocal(type); }
public ILGenerator GetILGenerator(int streamSize) { if (ilgen == null) { ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize); } return ilgen; }
public ILGenerator GetILGenerator(int streamSize) { if (rva != -1) { throw new InvalidOperationException(); } if (ilgen == null) { ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize); } return ilgen; }
public EmitCalculator(string term, int a, int b, int c, int d) { this.dm = new DynamicMethod( "Evaluate" , typeof(int) , new Type[] {typeof(int),typeof(int),typeof(int),typeof(int),typeof(int)} , typeof(int) ); this.tokens = term.Split(new Char[] {' '}); this.ilGen = dm.GetILGenerator(); this.GenCode(); Evaluate eval = (Evaluate) dm.CreateDelegate(typeof(Evaluate)); Console.WriteLine(eval(a, b, c, d, 0)); }
public CodeGen(Stmt stmt, string moduleName) { if (string.IsNullOrEmpty(moduleName)) throw new ArgumentException("must have a module name", "moduleName"); _stmt = stmt; _moduleName = moduleName; if (Path.GetFileName(moduleName) != moduleName) throw new Exception("can only output into current directory!"); var filename = Path.GetFileNameWithoutExtension(moduleName); var asmName = new AssemblyName(filename); _asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save); _modb = _asmb.DefineDynamicModule(moduleName); _typeBuilder = _modb.DefineType("Foo"); _methb = _typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), Type.EmptyTypes); _il = _methb.GetILGenerator(); SymbolTable = new Dictionary<string, LocalBuilder>(); }
public bool TryEmitDeserialiseCode(ILGenerator ilg, ThrowBlockGatherer throwBlocks, ICollection <string> errors, string name, Type targetType, LocalBuilder value, LocalBuilder unpacker, LocalBuilder contextLocal, DasherContext context, UnexpectedFieldBehaviour unexpectedFieldBehaviour) { var lblValidateArrayLength = ilg.DefineLabel(); var lblExit = ilg.DefineLabel(); // read the array length var count = ilg.DeclareLocal(typeof(int)); ilg.Emit(OpCodes.Ldloc, unpacker); ilg.Emit(OpCodes.Ldloca, count); ilg.Emit(OpCodes.Call, Methods.Unpacker_TryReadArrayLength); ilg.Emit(OpCodes.Brtrue_S, lblValidateArrayLength); // test for empty map (empty type) ilg.Emit(OpCodes.Ldloc, unpacker); ilg.Emit(OpCodes.Call, Methods.Unpacker_TryPeekEmptyMap); throwBlocks.ThrowIfFalse(() => { ilg.Emit(OpCodes.Ldstr, "Union values must be encoded as an array for property \"{0}\" of type \"{1}\""); ilg.Emit(OpCodes.Ldstr, name); ilg.LoadType(value.LocalType); ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object); ilg.LoadType(targetType); ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type); ilg.Emit(OpCodes.Throw); }); ilg.Emit(OpCodes.Ldnull); ilg.Emit(OpCodes.Stloc, value); ilg.Emit(OpCodes.Br, lblExit); // ensure we have two items in the array ilg.MarkLabel(lblValidateArrayLength); ilg.Emit(OpCodes.Ldloc, count); ilg.Emit(OpCodes.Ldc_I4_2); throwBlocks.ThrowIfNotEqual(() => { ilg.Emit(OpCodes.Ldstr, "Union array should have 2 elements (not {0}) for property \"{1}\" of type \"{2}\""); ilg.Emit(OpCodes.Ldloc, count); ilg.Emit(OpCodes.Box, typeof(int)); ilg.Emit(OpCodes.Ldstr, name); ilg.LoadType(value.LocalType); ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object_Object); ilg.LoadType(targetType); ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type); ilg.Emit(OpCodes.Throw); }); // read the serialised type name var typeName = ilg.DeclareLocal(typeof(string)); ilg.Emit(OpCodes.Ldloc, unpacker); ilg.Emit(OpCodes.Ldloca, typeName); ilg.Emit(OpCodes.Call, Methods.Unpacker_TryReadString); throwBlocks.ThrowIfFalse(() => { ilg.Emit(OpCodes.Ldstr, "Unable to read union type name for property \"{0}\" of type \"{1}\""); ilg.Emit(OpCodes.Ldstr, name); ilg.LoadType(value.LocalType); ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object); ilg.LoadType(targetType); ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type); ilg.Emit(OpCodes.Throw); }); var success = true; // loop through types within the union, looking for a matching type name var labelNextType = ilg.DefineLabel(); foreach (var type in value.LocalType.GetGenericArguments()) { var expectedTypeName = UnionEncoding.GetTypeName(type); ilg.Emit(OpCodes.Ldloc, typeName); ilg.Emit(OpCodes.Ldstr, expectedTypeName); ilg.Emit(OpCodes.Call, Methods.String_Equals_String_String); // continue if this type doesn't match the union's values ilg.Emit(OpCodes.Brfalse, labelNextType); // we have a match // read the value var readValue = ilg.DeclareLocal(type); if (!DeserialiserEmitter.TryEmitDeserialiseCode(ilg, throwBlocks, errors, name, targetType, readValue, unpacker, context, contextLocal, unexpectedFieldBehaviour)) { errors.Add($"Unable to deserialise union member type {type}"); success = false; } // create the union ilg.Emit(OpCodes.Ldloc, readValue); ilg.Emit(OpCodes.Call, value.LocalType.GetMethod(nameof(Union <int, int> .Create), new[] { type })); // store it in the result value ilg.Emit(OpCodes.Stloc, value); // exit the loop ilg.Emit(OpCodes.Br, lblExit); ilg.MarkLabel(labelNextType); labelNextType = ilg.DefineLabel(); } // If we exhaust the loop, throws ilg.MarkLabel(labelNextType); throwBlocks.Throw(() => { // TODO include received type name in error message and some more general info ilg.Emit(OpCodes.Ldstr, "No match on union type"); ilg.Emit(OpCodes.Newobj, Methods.Exception_Ctor_String); ilg.Emit(OpCodes.Throw); }); ilg.MarkLabel(lblExit); return(success); }
public static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo) { var dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module); ILGenerator il = dynamicMethod.GetILGenerator(); ParameterInfo[] ps = methodInfo.GetParameters(); var paramTypes = new Type[ps.Length]; for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { paramTypes[i] = ps[i].ParameterType.GetElementType(); } else { paramTypes[i] = ps[i].ParameterType; } } var locals = new LocalBuilder[paramTypes.Length]; for (int i = 0; i < paramTypes.Length; i++) { locals[i] = il.DeclareLocal(paramTypes[i], true); } for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldarg_1); EmitFastInt(il, i); il.Emit(OpCodes.Ldelem_Ref); EmitCastToReference(il, paramTypes[i]); il.Emit(OpCodes.Stloc, locals[i]); } if (!methodInfo.IsStatic) { il.Emit(OpCodes.Ldarg_0); } for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { il.Emit(OpCodes.Ldloca_S, locals[i]); } else { il.Emit(OpCodes.Ldloc, locals[i]); } } if (methodInfo.IsStatic) { il.EmitCall(OpCodes.Call, methodInfo, null); } else { il.EmitCall(OpCodes.Callvirt, methodInfo, null); } if (methodInfo.ReturnType == typeof(void)) { il.Emit(OpCodes.Ldnull); } else { EmitBoxIfNeeded(il, methodInfo.ReturnType); } for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { il.Emit(OpCodes.Ldarg_1); EmitFastInt(il, i); il.Emit(OpCodes.Ldloc, locals[i]); if (locals[i].LocalType.IsValueType) { il.Emit(OpCodes.Box, locals[i].LocalType); } il.Emit(OpCodes.Stelem_Ref); } } il.Emit(OpCodes.Ret); return((FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler))); }
private void Store(string name, Type type, ILGenerator il) { if (symbolTable.ContainsKey(name)) { LocalBuilder locb = (LocalBuilder)symbolTable[name]; if (locb.LocalType == type || (locb.LocalType == typeof(double) && type == typeof(int))) { il.Emit(OpCodes.Stloc, locb); } else { throw new Exception("'" + name + "' is of type " + locb.LocalType.Name + " but attempted to store value of type " + type.Name); } } else { throw new Exception("undeclared variable '" + name + "'"); } }
public static IEnumerable <CodeInstruction> HandleBlockingThingJob(MethodBase __originalMethod, IEnumerable <CodeInstruction> instructions, ILGenerator ilGen) { var code = instructions.ToList(); int insertIdx = -1; for (int i = 0; i < code.Count; i++) { if (code[i].opcode == OpCodes.Ldc_I4_4 && code[i + 1].opcode == OpCodes.Bne_Un_S) // if (thing.def.category == ThingCategory.Plant) { insertIdx = i + 2; } } if (insertIdx == -1) { Log.Error($"[HandleBlockingPlants] Can't find insertion place"); return(code); } bool isRoofUtility = __originalMethod.DeclaringType == typeof(RoofUtility); var continueLabel = ilGen.DefineLabel(); code[insertIdx].labels.Add(continueLabel); code.InsertRange(insertIdx, new [] { // if (!CanCutBlockingPlant(worker, thing)) return null new CodeInstruction(OpCodes.Ldarg_1), isRoofUtility ? new CodeInstruction(OpCodes.Ldarg_0) : new CodeInstruction(OpCodes.Ldloc_0), // RoofUtility blocker from argument, GenConstruct blocker from local var new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(HandleBlockingPlants), nameof(HandleBlockingPlants.CanCutBlockingPlant))), new CodeInstruction(OpCodes.Brtrue_S, continueLabel), new CodeInstruction(OpCodes.Ldnull), new CodeInstruction(OpCodes.Ret) }); return(code); }
void EmitSpecial(ILGenerator gen) { switch (special) { case Specials.Label: gen.MarkLabel((Label)operand); break; case Specials.BeginTry: gen.BeginExceptionBlock(); break; case Specials.BeginFinally: gen.BeginFinallyBlock(); break; case Specials.EndTry: gen.EndExceptionBlock(); break; case Specials.BeginTotemScope: gen.Emit(OpCodes.Nop); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Newobj, Generator.scope_ctor); gen.Emit(OpCodes.Stloc, (LocalBuilder)operand); gen.BeginExceptionBlock(); break; case Specials.EndTotemScope: var endFinallyLabel = gen.DefineLabel(); gen.BeginFinallyBlock(); gen.Emit(OpCodes.Ldloc, (LocalBuilder)operand); gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, endFinallyLabel); gen.Emit(OpCodes.Ldloc, (LocalBuilder)operand); gen.Emit(OpCodes.Callvirt, Generator.dispose); gen.Emit(OpCodes.Nop); gen.MarkLabel(endFinallyLabel); gen.EndExceptionBlock(); break; default: throw new InvalidOperationException("default:special"); } }
public void Implement(ILGenerator ilg) { DMethodBody body = Body; body.DeclareLocals(ilg); for (int i = 0 ; i != body.Code.Length ; i++) { if (!body.Code[i].Emit(ilg)) throw new Exception(String.Format("Code gen failure at i={0} {1}", i, body.Code[i].opCode)); } }
private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet) { OpCode obj, index, value; var fail = il.DefineLabel(); if (mapField == null) { index = OpCodes.Ldarg_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_2; } else { il.DeclareLocal(typeof(int)); index = OpCodes.Ldloc_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_3; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, mapField); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldloca_S, (byte)0); il.EmitCall(OpCodes.Callvirt, tryGetValue, null); il.Emit(OpCodes.Brfalse, fail); } var labels = new Label[members.Count]; for (var i = 0; i < labels.Length; i++) { labels[i] = il.DefineLabel(); } il.Emit(index); il.Emit(OpCodes.Switch, labels); il.MarkLabel(fail); il.Emit(OpCodes.Ldstr, "name"); il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Throw); for (var i = 0; i < labels.Length; i++) { il.MarkLabel(labels[i]); var member = members[i]; var isFail = true; void WriteField(FieldInfo fieldToWrite) { if (!fieldToWrite.FieldType.IsByRef) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.Emit(OpCodes.Ldfld, fieldToWrite); if (fieldToWrite.FieldType.IsValueType) { il.Emit(OpCodes.Box, fieldToWrite.FieldType); } } else { il.Emit(value); Cast(il, fieldToWrite.FieldType, false); il.Emit(OpCodes.Stfld, fieldToWrite); } il.Emit(OpCodes.Ret); isFail = false; } } if (member is FieldInfo field) { WriteField(field); } else if (member is PropertyInfo prop) { var propType = prop.PropertyType; bool isByRef = propType.IsByRef, isValid = true; if (isByRef) { if (!isGet && prop.CustomAttributes.Any(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute")) { isValid = false; // can't assign indirectly to ref-readonly } propType = propType.GetElementType(); // from "ref Foo" to "Foo" } var accessor = (isGet | isByRef) ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors); if (accessor == null && allowNonPublicAccessors && !isByRef) { // No getter/setter, use backing field instead if it exists var backingField = $"<{prop.Name}>k__BackingField"; field = prop.DeclaringType?.GetField(backingField, BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { WriteField(field); } } else if (isValid && prop.CanRead && accessor != null) { il.Emit(obj); Cast(il, type, true); // cast the input object to the right target type if (isGet) { il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null); if (isByRef) { il.Emit(OpCodes.Ldobj, propType); // defererence if needed } if (propType.IsValueType) { il.Emit(OpCodes.Box, propType); // box the value if needed } } else { // when by-ref, we get the target managed pointer *first*, i.e. put obj.TheRef on the stack if (isByRef) { il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null); } // load the new value, and type it il.Emit(value); Cast(il, propType, false); if (isByRef) // assign to the managed pointer { il.Emit(OpCodes.Stobj, propType); } else // call the setter { il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null); } } il.Emit(OpCodes.Ret); isFail = false; } } if (isFail) { il.Emit(OpCodes.Br, fail); } } }
public void __ReleaseILGenerator() { if (ilgen != null) { #if !NO_SYMBOL_WRITER if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000), this); } #endif rva = ilgen.WriteBody(initLocals); #if !NO_SYMBOL_WRITER if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.CloseMethod(); } #endif ilgen = null; } }
internal override void MarkSequencePoint(LambdaExpression method, MethodBase methodBase, ILGenerator ilg, DebugInfoExpression sequencePoint) { MethodBuilder builder = methodBase as MethodBuilder; if (builder != null) { ilg.MarkSequencePoint(GetSymbolWriter(builder, sequencePoint.Document), sequencePoint.StartLine, sequencePoint.StartColumn, sequencePoint.EndLine, sequencePoint.EndColumn); } }
private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult) { const int dispatchPointerIndex = 0; const int memberDispIdIndex = 1; const int flagsIndex = 2; const int dispParamsIndex = 3; const int resultIndex = 4; const int exceptInfoIndex = 5; const int argErrIndex = 6; Debug.Assert(argErrIndex + 1 == typeof(IDispatchInvokeDelegate).GetMethod("Invoke").GetParameters().Length); Type[] paramTypes = new Type[argErrIndex + 1]; paramTypes[dispatchPointerIndex] = typeof(IntPtr); paramTypes[memberDispIdIndex] = typeof(int); paramTypes[flagsIndex] = typeof(ComTypes.INVOKEKIND); paramTypes[dispParamsIndex] = typeof(ComTypes.DISPPARAMS).MakeByRefType(); paramTypes[resultIndex] = typeof(Variant).MakeByRefType(); paramTypes[exceptInfoIndex] = typeof(ExcepInfo).MakeByRefType(); paramTypes[argErrIndex] = typeof(uint).MakeByRefType(); // Define the dynamic method in our assembly so we skip verification DynamicMethod dm = new DynamicMethod("IDispatchInvoke", typeof(int), paramTypes, DynamicModule); ILGenerator method = dm.GetILGenerator(); // return functionPtr(...) EmitLoadArg(method, dispatchPointerIndex); EmitLoadArg(method, memberDispIdIndex); // burn the address of our empty IID in directly. This is never freed, relocated, etc... // Note passing this as a Guid directly results in a ~30% perf hit for IDispatch invokes so // we also pass it directly as an IntPtr instead. if (IntPtr.Size == 4) { method.Emit(OpCodes.Ldc_I4, UnsafeMethods.NullInterfaceId.ToInt32()); // riid } else { method.Emit(OpCodes.Ldc_I8, UnsafeMethods.NullInterfaceId.ToInt64()); // riid } method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4_0); // lcid EmitLoadArg(method, flagsIndex); EmitLoadArg(method, dispParamsIndex); if (returnResult) { EmitLoadArg(method, resultIndex); } else { method.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField("Zero")); } EmitLoadArg(method, exceptInfoIndex); EmitLoadArg(method, argErrIndex); // functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET) int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr)); EmitLoadArg(method, dispatchPointerIndex); method.Emit(OpCodes.Ldind_I); method.Emit(OpCodes.Ldc_I4, idispatchInvokeOffset); method.Emit(OpCodes.Add); method.Emit(OpCodes.Ldind_I); System.Reflection.Emit.SignatureHelper signature = System.Reflection.Emit.SignatureHelper.GetMethodSigHelper(CallingConvention.Winapi, typeof(int)); Type[] invokeParamTypes = new Type[] { typeof(IntPtr), // dispatchPointer typeof(int), // memberDispId typeof(IntPtr), // riid typeof(int), // lcid typeof(ushort), // flags typeof(IntPtr), // dispParams typeof(IntPtr), // result typeof(IntPtr), // excepInfo typeof(IntPtr), // argErr }; signature.AddArguments(invokeParamTypes, null, null); method.Emit(OpCodes.Calli, signature); method.Emit(OpCodes.Ret); return((IDispatchInvokeDelegate)dm.CreateDelegate(typeof(IDispatchInvokeDelegate))); }
static void Main() { string name = "InMemory"; AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.Run); ModuleBuilder modBldr = asmBldr.DefineDynamicModule(name); TypeBuilder tb = modBldr.DefineType("DemoVararg"); // Create a vararg method with no return value and one // string argument. (The string argument type is the only // element of an array of Type objects.) // MethodBuilder mb1 = tb.DefineMethod("VarargMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.VarArgs, null, new Type[] { typeof(string) }); ILGenerator il1 = mb1.GetILGenerator(); LocalBuilder locAi = il1.DeclareLocal(typeof(ArgIterator)); LocalBuilder locNext = il1.DeclareLocal(typeof(bool)); Label labelCheckCondition = il1.DefineLabel(); Label labelNext = il1.DefineLabel(); // Load the fixed argument and print it. il1.Emit(OpCodes.Ldarg_0); il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(string) })); // Load the address of the local variable represented by // locAi, which will hold the ArgIterator. il1.Emit(OpCodes.Ldloca_S, locAi); // Load the address of the argument list, and call the // ArgIterator constructor that takes an array of runtime // argument handles. il1.Emit(OpCodes.Arglist); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetConstructor(new Type[] { typeof(RuntimeArgumentHandle) })); // Enter the loop at the point where the remaining argument // count is tested. il1.Emit(OpCodes.Br_S, labelCheckCondition); // At the top of the loop, call GetNextArg to get the next // argument from the ArgIterator. Convert the typed reference // to an object reference and write the object to the console. il1.MarkLabel(labelNext); il1.Emit(OpCodes.Ldloca_S, locAi); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetNextArg", Type.EmptyTypes)); il1.Emit(OpCodes.Call, typeof(TypedReference).GetMethod("ToObject")); il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(object) })); il1.MarkLabel(labelCheckCondition); il1.Emit(OpCodes.Ldloca_S, locAi); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetRemainingCount")); // If the remaining count is greater than zero, go to // the top of the loop. il1.Emit(OpCodes.Ldc_I4_0); il1.Emit(OpCodes.Cgt); il1.Emit(OpCodes.Stloc_1); il1.Emit(OpCodes.Ldloc_1); il1.Emit(OpCodes.Brtrue_S, labelNext); il1.Emit(OpCodes.Ret); // Create a method that contains a call to the vararg // method. MethodBuilder mb2 = tb.DefineMethod("CallVarargMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes); ILGenerator il2 = mb2.GetILGenerator(); // Push arguments on the stack: one for the fixed string // parameter, and two for the list. il2.Emit(OpCodes.Ldstr, "Hello "); il2.Emit(OpCodes.Ldstr, "world "); il2.Emit(OpCodes.Ldc_I4, 2006); // Call the vararg method, specifying the types of the // arguments in the list. il2.EmitCall(OpCodes.Call, mb1, new Type[] { typeof(string), typeof(int) }); il2.Emit(OpCodes.Ret); Type type = tb.CreateType(); type.GetMethod("CallVarargMethod").Invoke(null, null); }
static void emit_ldarg(ILGenerator code, int index) { switch (index) { case 0: code.Emit(OpCodes.Ldarg_0); break; case 1: code.Emit(OpCodes.Ldarg_1); break; case 2: code.Emit(OpCodes.Ldarg_2); break; case 3: code.Emit(OpCodes.Ldarg_3); break; default: if (index < 0x100) code.Emit(OpCodes.Ldarg_S, (byte) index); else if (index < 0x8000) code.Emit(OpCodes.Ldarg_S, (short) index); else code.Emit(OpCodes.Ldarg, index); break; } }
static void EmitPrepareArgStore(ILGenerator ilg, LocalBuilder bufLocal, int argnum) { EmitComputeBufferLoc(ilg, bufLocal, argnum); EmitLoadArg(ilg, argnum); }
public override void GenerateAsStatement (ILGenerator gen) { exp.GenerateSet (gen, new CodeAddOne (exp)); }
internal FieldNullable(LocalBuilder stack, ILGenerator generator) : base(ToNullable(stack, generator), generator) { ValueInfo = typeof(Nullable <T>).GetProperty("Value").GetGetMethod(); HasValueInfo = typeof(Nullable <T>).GetProperty("HasValue").GetGetMethod(); GetValueOrDefaultInfo = typeof(Nullable <T>).GetMethod("GetValueOrDefault", Type.EmptyTypes); }
private void GenerateMethod(Type interfaceType, FieldBuilder handlerField, TypeBuilder typeBuilder) { MetaDataFactory.Add(interfaceType); MethodInfo[] interfaceMethods = interfaceType.GetMethods(); if (interfaceMethods != null) { for (int i = 0; i < interfaceMethods.Length; i++) { MethodInfo methodInfo = interfaceMethods[i]; // Get the method parameters since we need to create an array // of parameter types ParameterInfo[] methodParams = methodInfo.GetParameters(); int numOfParams = methodParams.Length; Type[] methodParameters = new Type[numOfParams]; // convert the ParameterInfo objects into Type for (int j = 0; j < numOfParams; j++) { methodParameters[j] = methodParams[j].ParameterType; } // create a new builder for the method in the interface MethodBuilder methodBuilder = typeBuilder.DefineMethod( methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard, methodInfo.ReturnType, methodParameters); #region ( "Handler Method IL Code" ) ILGenerator methodIL = methodBuilder.GetILGenerator(); // Emit a declaration of a local variable if there is a return // type defined if (!methodInfo.ReturnType.Equals(typeof(void))) { methodIL.DeclareLocal(methodInfo.ReturnType); if (methodInfo.ReturnType.IsValueType && !methodInfo.ReturnType.IsPrimitive) { methodIL.DeclareLocal(methodInfo.ReturnType); } } // if we have any parameters for the method, then declare an // Object array local var. if (numOfParams > 0) { methodIL.DeclareLocal(typeof(System.Object[])); } // declare a label for invoking the handler Label handlerLabel = methodIL.DefineLabel(); // declare a lable for returning from the mething Label returnLabel = methodIL.DefineLabel(); // load "this" methodIL.Emit(OpCodes.Ldarg_0); // load the handler instance variable methodIL.Emit(OpCodes.Ldfld, handlerField); // jump to the handlerLabel if the handler instance variable is not null methodIL.Emit(OpCodes.Brtrue_S, handlerLabel); // the handler is null, so return null if the return type of // the method is not void, otherwise return nothing if (!methodInfo.ReturnType.Equals(typeof(void))) { if (methodInfo.ReturnType.IsValueType && !methodInfo.ReturnType.IsPrimitive && !methodInfo.ReturnType.IsEnum) { methodIL.Emit(OpCodes.Ldloc_1); } else { // load null onto the stack methodIL.Emit(OpCodes.Ldnull); } // store the null return value methodIL.Emit(OpCodes.Stloc_0); // jump to return methodIL.Emit(OpCodes.Br_S, returnLabel); } // the handler is not null, so continue with execution methodIL.MarkLabel(handlerLabel); // load "this" methodIL.Emit(OpCodes.Ldarg_0); // load the handler methodIL.Emit(OpCodes.Ldfld, handlerField); // load "this" since its needed for the call to invoke methodIL.Emit(OpCodes.Ldarg_0); // load the name of the interface, used to get the MethodInfo object // from MetaDataFactory methodIL.Emit(OpCodes.Ldstr, interfaceType.FullName); // load the index, used to get the MethodInfo object // from MetaDataFactory methodIL.Emit(OpCodes.Ldc_I4, i); // invoke GetMethod in MetaDataFactory methodIL.Emit(OpCodes.Call, typeof(DynamicProxy.MetaDataFactory).GetMethod( "GetMethod", new Type[] { typeof(string), typeof(int) })); // load the number of parameters onto the stack methodIL.Emit(OpCodes.Ldc_I4, numOfParams); // create a new array, using the size that was just pused on the stack methodIL.Emit(OpCodes.Newarr, typeof(System.Object)); // if we have any parameters, then iterate through and set the values // of each element to the corresponding arguments if (numOfParams > 0) { methodIL.Emit(OpCodes.Stloc_1); for (int j = 0; j < numOfParams; j++) { methodIL.Emit(OpCodes.Ldloc_1); methodIL.Emit(OpCodes.Ldc_I4, j); methodIL.Emit(OpCodes.Ldarg, j + 1); if (methodParameters[j].IsValueType) { methodIL.Emit(OpCodes.Box, methodParameters[j]); } methodIL.Emit(OpCodes.Stelem_Ref); } methodIL.Emit(OpCodes.Ldloc_1); } // call the Invoke method methodIL.Emit(OpCodes.Callvirt, typeof(DynamicProxy.IProxyInvocationHandler).GetMethod("Invoke")); if (!methodInfo.ReturnType.Equals(typeof(void))) { // if the return type if a value type, then unbox the return value // so that we don't get junk. if (methodInfo.ReturnType.IsValueType) { methodIL.Emit(OpCodes.Unbox, methodInfo.ReturnType); if (methodInfo.ReturnType.IsEnum) { methodIL.Emit(OpCodes.Ldind_I4); } else if (!methodInfo.ReturnType.IsPrimitive) { methodIL.Emit(OpCodes.Ldobj, methodInfo.ReturnType); } else { methodIL.Emit((OpCode)opCodeTypeMapper[methodInfo.ReturnType]); } } // store the result methodIL.Emit(OpCodes.Stloc_0); // jump to the return statement methodIL.Emit(OpCodes.Br_S, returnLabel); // mark the return statement methodIL.MarkLabel(returnLabel); // load the value stored before we return. This will either be // null (if the handler was null) or the return value from Invoke methodIL.Emit(OpCodes.Ldloc_0); } else { // pop the return value that Invoke returned from the stack since // the method's return type is void. methodIL.Emit(OpCodes.Pop); //mark the return statement methodIL.MarkLabel(returnLabel); } // Return methodIL.Emit(OpCodes.Ret); #endregion } } // Iterate through the parent interfaces and recursively call this method foreach (Type parentType in interfaceType.GetInterfaces()) { GenerateMethod(parentType, handlerField, typeBuilder); } }
public static IEnumerable<CodeInstruction> Formatted(IEnumerable<CodeInstruction> instructions, ILGenerator iLGenerator) { List<CodeInstruction> instructionsList = instructions.ToList(); Type loadLockObjectType = typeof(List<string>); List<CodeInstruction> loadLockObjectInstructions = new List<CodeInstruction> { new CodeInstruction(OpCodes.Ldarg_1), }; List<CodeInstruction> searchInstructions = loadLockObjectInstructions.ListFullCopy(); searchInstructions.Add(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Enumerable), "ToList").MakeGenericMethod(typeof(string)))); searchInstructions.Add(new CodeInstruction(OpCodes.Stloc_S, 5)); Type loadLockObjectType2 = typeof(List<object>); List<CodeInstruction> loadLockObjectInstructions2 = new List<CodeInstruction> { new CodeInstruction(OpCodes.Ldarg_2), }; List<CodeInstruction> searchInstructions2 = loadLockObjectInstructions2.ListFullCopy(); searchInstructions2.Add(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Enumerable), "ToList").MakeGenericMethod(typeof(object)))); searchInstructions2.Add(new CodeInstruction(OpCodes.Stloc_S, 6)); /* Original PathFinder.FindPath ---START ORIG--- IL_000b: ldsfld bool Verse.GrammarResolverSimple::working ---END ORIG--- ---START TARGET--- IL_0000: ldc-i4-1 ---END TARGET--- */ //LocalBuilder tmpCells = iLGenerator.DeclareLocal(typeof(List<IntVec3>)); int i = 0; //yield return new CodeInstruction(OpCodes.Newobj, typeof(List<IntVec3>).GetConstructor(Type.EmptyTypes)); //yield return new CodeInstruction(OpCodes.Stloc_S, tmpCells.LocalIndex); int matchesFound = 0; while (i < instructionsList.Count) { //---START ORIG-- - // IL_000b: ldsfld bool Verse.GrammarResolverSimple::working //-- - END ORIG-- - //---START TARGET-- - //IL_0000: Ldc_I4_0 //-- - END TARGET-- - if ( instructionsList[i].opcode == OpCodes.Ldsfld && (FieldInfo)instructionsList[i].operand == AccessTools.Field(typeof(GrammarResolverSimple), "working") ) { instructionsList[i].opcode = OpCodes.Ldc_I4_1; instructionsList[i].operand = null; yield return instructionsList[i]; i++; } else if (RimThreadedHarmony.IsCodeInstructionsMatching(searchInstructions, instructionsList, i)) { matchesFound++; foreach (CodeInstruction codeInstruction in RimThreadedHarmony.GetLockCodeInstructions( iLGenerator, instructionsList, i, searchInstructions.Count, loadLockObjectInstructions, loadLockObjectType)) { yield return codeInstruction; } i += searchInstructions.Count; } else if (RimThreadedHarmony.IsCodeInstructionsMatching(searchInstructions2, instructionsList, i)) { matchesFound++; foreach (CodeInstruction codeInstruction in RimThreadedHarmony.GetLockCodeInstructions( iLGenerator, instructionsList, i, searchInstructions2.Count, loadLockObjectInstructions2, loadLockObjectType2)) { yield return codeInstruction; } i += searchInstructions.Count; } else { yield return instructionsList[i]; i++; } } if (matchesFound < 2) { Log.Error("IL code instructions not found"); } }
public void Emit(ILGenerator gen) { switch (type) { case InstructionType.OpCode: EmitOpCode(gen); break; case InstructionType.Special: EmitSpecial(gen); break; default: throw new InvalidOperationException("Invalid type"); } }
private static void EmitCreationMethod(Type targetType, ConstructorInfo constructor, ILGenerator il) { EmitParameters(il, constructor.GetParameters()); EmitObjectCreationAndExit(constructor, il, targetType); }
static void EmitTypeStore(ILGenerator ilg, LocalBuilder bufLocal, TypeInfo.TypeDescriptor t, int argnum) { ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 12); ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldc_I4, (Int32)t.tag); ilg.Emit(OpCodes.Stind_I4); }
private static void EmitArrayElementToStack(ILGenerator il, int i) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); }
static void EmitLoadArg(ILGenerator ilg, int argnum) { switch (argnum) { case 0: ilg.Emit(OpCodes.Ldarg_1); break; case 1: ilg.Emit(OpCodes.Ldarg_2); break; case 2: ilg.Emit(OpCodes.Ldarg_3); break; default: if (argnum < 254) ilg.Emit(OpCodes.Ldarg_S, argnum + 1); else ilg.Emit(OpCodes.Ldarg, argnum + 1); break; } }
private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet) { OpCode obj, index, value; Label fail = il.DefineLabel(); if (mapField == null) { index = OpCodes.Ldarg_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_2; } else { il.DeclareLocal(typeof(int)); index = OpCodes.Ldloc_0; obj = OpCodes.Ldarg_1; value = OpCodes.Ldarg_3; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, mapField); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldloca_S, (byte)0); il.EmitCall(OpCodes.Callvirt, tryGetValue, null); il.Emit(OpCodes.Brfalse, fail); } Label[] labels = new Label[members.Count]; for (int i = 0; i < labels.Length; i++) { labels[i] = il.DefineLabel(); } il.Emit(index); il.Emit(OpCodes.Switch, labels); il.MarkLabel(fail); il.Emit(OpCodes.Ldstr, "name"); il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Throw); for (int i = 0; i < labels.Length; i++) { il.MarkLabel(labels[i]); var member = members[i]; bool isFail = true; FieldInfo field; PropertyInfo prop; if ((field = member as FieldInfo) != null) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.Emit(OpCodes.Ldfld, field); if (_IsValueType(field.FieldType)) { il.Emit(OpCodes.Box, field.FieldType); } } else { il.Emit(value); Cast(il, field.FieldType, false); il.Emit(OpCodes.Stfld, field); } il.Emit(OpCodes.Ret); isFail = false; } else if ((prop = member as PropertyInfo) != null) { MethodInfo accessor; if (prop.CanRead && (accessor = isGet ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors)) != null) { il.Emit(obj); Cast(il, type, true); if (isGet) { il.EmitCall(_IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null); if (_IsValueType(prop.PropertyType)) { il.Emit(OpCodes.Box, prop.PropertyType); } } else { il.Emit(value); Cast(il, prop.PropertyType, false); il.EmitCall(_IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null); } il.Emit(OpCodes.Ret); isFail = false; } } if (isFail) { il.Emit(OpCodes.Br, fail); } } }
/// <summary> /// TOO MUCH OF A MESS TO EXPLAIN /// </summary> /// <returns>Madness.</returns> private static IEnumerable <CodeInstruction> ReorderWidgetFromEventToInputTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { MethodInfo GetCurrent = AccessTools.Property(typeof(Event), nameof(Event.current)).GetGetMethod(); MethodInfo GetRawType = AccessTools.Property(typeof(Event), nameof(Event.rawType)).GetGetMethod(); MethodInfo NoMouseButtonsPressed = AccessTools.Method(typeof(Numbers), nameof(NoMouseButtonsPressed)); MethodInfo WasClicked = AccessTools.Method(typeof(Numbers), nameof(WasClicked)); FieldInfo released = AccessTools.Field(typeof(ReorderableWidget), "released"); bool yieldNext = true; List <CodeInstruction> instructionArr = instructions.ToList(); for (int i = 0; i < instructionArr.ToArray().Length; i++) { CodeInstruction instruction = instructionArr[i]; if (instruction.operand != null && instruction.operand == GetCurrent) { if (instructionArr[i + 1].operand != null && instructionArr[i + 1].operand == GetRawType) { //L_02bc: Label1 //L_02bc: call UnityEngine.Event get_current() //L_02c1: callvirt EventType get_rawType() //L_02c6: ldc.i4.1 // => // call Input.GetMouseButtonUp(1) (or 0) yield return(new CodeInstruction(OpCodes.Nop) { labels = new List <Label> { generator.DefineLabel() } }); instruction.opcode = OpCodes.Call; instruction.operand = NoMouseButtonsPressed; instructionArr.RemoveAt(i + 1); } } if (instruction.opcode == OpCodes.Stsfld && instruction.operand == released) { yield return(instruction); CodeInstruction codeInst = new CodeInstruction(OpCodes.Ldarg_2) { labels = new List <Label> { generator.DefineLabel(), } }; codeInst.labels.AddRange(instructionArr[i + 1].labels); yield return(codeInst); yield return(new CodeInstruction(OpCodes.Call, WasClicked)); yieldNext = false; } if (!yieldNext && instruction.opcode == OpCodes.Ldarg_1) { yieldNext = true; } if (yieldNext) { yield return(instruction); } if (instruction.opcode == OpCodes.Call && instruction.operand == AccessTools.Method(typeof(Mouse), nameof(Mouse.IsOver))) { yield return(new CodeInstruction(OpCodes.And)); } } }
private void EmitArrayIndexer() { Node.Target.AcceptVisitor(ILGenerator, Visitor); Node.Arguments.ForEach(arg => arg.AcceptVisitor(ILGenerator, Visitor)); ILGenerator.EmitLoadElementByType(Type.GetElementType()); }
private static void AddProperty( PropertyInfo propertyInfo, Type composedPropertyType, DataMemberAttribute dataMemberAttribute, TypeBuilder typeBuilder ) { string propertyName = dataMemberAttribute.Name as string ?? propertyInfo.Name; // generating property PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, composedPropertyType, null); Type dataMemberAttributeType = typeof(DataMemberAttribute); var dataMemberProps = new PropertyInfo[] { dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.Name)), dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.IsRequired)), dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.EmitDefaultValue)) }; var dataMemberPropValues = new object[] { propertyName, dataMemberAttribute.IsRequired, dataMemberAttribute.EmitDefaultValue }; CustomAttributeBuilder dataMemberAttributeBuilder = new CustomAttributeBuilder( dataMemberAttributeType.GetConstructor(Type.EmptyTypes), new object[0], dataMemberProps, dataMemberPropValues ); propertyBuilder.SetCustomAttribute(dataMemberAttributeBuilder); // generating private field FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, composedPropertyType, FieldAttributes.Private); CustomAttributeBuilder hideFieldAttributeBuilder = new CustomAttributeBuilder( typeof(DebuggerBrowsableAttribute).GetConstructor(new[] { typeof(DebuggerBrowsableState) }), new object[] { DebuggerBrowsableState.Never } ); fieldBuilder.SetCustomAttribute(hideFieldAttributeBuilder); // generating public getter/setter MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, composedPropertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { composedPropertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); }
private static TypeBuilder AddPropertyToTypeBuilder(TypeBuilder typeBuilder, Type properType, string name) { if (typeof(IList).IsAssignableFrom(properType)) { //ignore } //if complex type - use recurrence else if (!(properType.GetTypeInfo().IsValueType || properType == typeof(string))) { properType = DecorateObjectWithAvroAttributes(properType).GetType(); } //mimic property PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, properType, null); var attributeConstructor = typeof(DataMemberAttribute).GetConstructor(new Type[] { }); var attributeProperties = typeof(DataMemberAttribute).GetProperties(); var attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new string[] { }, attributeProperties.Where(p => p.Name == "Name").ToArray(), new object[] { name }); propertyBuilder.SetCustomAttribute(attributeBuilder); //Add nullable attribute if (Nullable.GetUnderlyingType(properType) != null || properType == typeof(string)) { var nullableAttributeConstructor = typeof(NullableSchemaAttribute).GetConstructor(new Type[] { }); var nullableAttributeBuilder = new CustomAttributeBuilder(nullableAttributeConstructor, new string[] { }, new PropertyInfo[] { }, new object[] { }); propertyBuilder.SetCustomAttribute(nullableAttributeBuilder); } // Define field FieldBuilder fieldBuilder = typeBuilder.DefineField(name, properType, FieldAttributes.Public); // Define "getter" for property MethodBuilder getterBuilder = typeBuilder.DefineMethod("get_" + name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, properType, Type.EmptyTypes); ILGenerator getterIL = getterBuilder.GetILGenerator(); getterIL.Emit(OpCodes.Ldarg_0); getterIL.Emit(OpCodes.Ldfld, fieldBuilder); getterIL.Emit(OpCodes.Ret); // Define "setter" for property MethodBuilder setterBuilder = typeBuilder.DefineMethod("set_" + name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { properType }); ILGenerator setterIL = setterBuilder.GetILGenerator(); setterIL.Emit(OpCodes.Ldarg_0); setterIL.Emit(OpCodes.Ldarg_1); setterIL.Emit(OpCodes.Stfld, fieldBuilder); setterIL.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterBuilder); propertyBuilder.SetSetMethod(setterBuilder); return(typeBuilder); }
public bool TryEmitSerialiseCode(ILGenerator ilg, ThrowBlockGatherer throwBlocks, ICollection <string> errors, LocalBuilder value, LocalBuilder packer, LocalBuilder contextLocal, DasherContext context) { // write header ilg.Emit(OpCodes.Ldloc, packer); ilg.Emit(OpCodes.Ldc_I4_2); ilg.Emit(OpCodes.Call, Methods.Packer_PackArrayHeader); // TODO might be faster if we a generated class having members for use with called 'Union<>.Match' var typeObj = ilg.DeclareLocal(typeof(Type)); ilg.Emit(OpCodes.Ldloc, value); ilg.Emit(OpCodes.Callvirt, value.LocalType.GetProperty(nameof(Union <int, int> .Type)).GetMethod); ilg.Emit(OpCodes.Stloc, typeObj); // write type name ilg.Emit(OpCodes.Ldloc, packer); ilg.Emit(OpCodes.Ldloc, typeObj); ilg.Emit(OpCodes.Call, Methods.UnionEncoding_GetTypeName); ilg.Emit(OpCodes.Call, Methods.Packer_Pack_String); var success = true; // loop through types within the union, looking for a match var doneLabel = ilg.DefineLabel(); var labelNextType = ilg.DefineLabel(); foreach (var type in value.LocalType.GetGenericArguments()) { ilg.LoadType(type); ilg.Emit(OpCodes.Ldloc, typeObj); ilg.Emit(OpCodes.Call, Methods.Object_Equals_Object_Object); // continue if this type doesn't match the union's values ilg.Emit(OpCodes.Brfalse, labelNextType); // we have a match // get the value var valueObj = ilg.DeclareLocal(type); ilg.Emit(OpCodes.Ldloc, value); ilg.Emit(OpCodes.Callvirt, value.LocalType.GetProperty(nameof(Union <int, int> .Value)).GetMethod); ilg.Emit(type.GetTypeInfo().IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); ilg.Emit(OpCodes.Stloc, valueObj); // write value if (!SerialiserEmitter.TryEmitSerialiseCode(ilg, throwBlocks, errors, valueObj, packer, context, contextLocal)) { errors.Add($"Unable to serialise union member type {type}"); success = false; } ilg.Emit(OpCodes.Br, doneLabel); ilg.MarkLabel(labelNextType); labelNextType = ilg.DefineLabel(); } ilg.MarkLabel(labelNextType); throwBlocks.Throw(() => { ilg.Emit(OpCodes.Ldstr, "No match on union type"); ilg.Emit(OpCodes.Newobj, Methods.Exception_Ctor_String); ilg.Emit(OpCodes.Throw); }); ilg.MarkLabel(doneLabel); return(success); }
/// <summary> /// Creates the SpringServicedComponent base class to derive all <see cref="ServicedComponent"/>s from. /// </summary> /// <example> /// <code> /// internal class SpringServicedComponent: BaseType /// { /// protected delegate object GetObjectHandler(ServicedComponent servicedComponent, string targetName); /// /// protected static readonly GetObjectHandler getObjectRef; /// /// static SpringServicedComponent() /// { /// // first look for a local copy /// System.Reflection.Assembly servicesAssembly; /// string servicesAssemblyPath = Path.Combine( /// new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName /// , "Spring.Services.dll" ); /// servicesAssembly = System.Reflection.Assembly.LoadFrom(servicesAssemblyPath); /// if (servicesAssembly == null) /// { /// // then let the normal loader handle the typeload /// servicesAssembly = System.Reflection.Assembly.Load("Spring.Services, culture=neutral, version=x.x.x.x, publicKey=xxxxxxxx"); /// } /// /// Type componentHelperType = servicesAssembly.GetType("Spring.EnterpriseServices.ServicedComponentHelper"); /// getObjectRef = (GetObjectHandler) Delegate.CreateDelegate(typeof(GetObjectHandler) /// , componentHelperType.GetMethod("GetObject")); /// } /// } /// </code> /// </example> public static Type CreateSpringServicedComponentType(ModuleBuilder module, Type baseType) { if (!typeof(ServicedComponent).IsAssignableFrom(baseType)) { throw new ArgumentException(string.Format("baseType must derive from {0}, was {1}", typeof(ServicedComponent).FullName, baseType), "baseType"); } Type delegateType = DefineDelegate(module); TypeBuilder typeBuilder = module.DefineType("SpringServicedComponent", System.Reflection.TypeAttributes.Public, baseType); ILGenerator il = null; FieldBuilder getObjectRef = typeBuilder.DefineField("getObject", delegateType, FieldAttributes.Family | FieldAttributes.Static); ConstructorBuilder typeCtor = typeBuilder.DefineTypeInitializer(); il = typeCtor.GetILGenerator(); Label methodEnd = il.DefineLabel(); Label loadType = il.DefineLabel(); Label tryBegin = il.BeginExceptionBlock(); LocalBuilder fldAssembly = il.DeclareLocal(typeof(Assembly)); LocalBuilder fldType = il.DeclareLocal(typeof(Type)); LocalBuilder fldArgs = il.DeclareLocal(typeof(object[])); LocalBuilder fldMethod = il.DeclareLocal(typeof(MethodBase)); il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly")); il.Emit(OpCodes.Callvirt, typeof(Assembly).GetProperty("Location").GetGetMethod()); il.Emit(OpCodes.Newobj, typeof(FileInfo).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Call, typeof(FileInfo).GetProperty("DirectoryName").GetGetMethod()); il.Emit(OpCodes.Ldstr, new FileInfo(typeof(ServicedComponentHelper).Assembly.Location).Name); il.Emit(OpCodes.Call, typeof(Path).GetMethod("Combine", new Type[] { typeof(string), typeof(string) })); il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("LoadFrom", new Type[] { typeof(string) })); il.Emit(OpCodes.Stloc, fldAssembly); il.Emit(OpCodes.Ldloc, fldAssembly); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, loadType); il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).Assembly.FullName); il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("Load", new Type[] { typeof(string) })); il.Emit(OpCodes.Stloc, fldAssembly); il.MarkLabel(loadType); il.Emit(OpCodes.Ldloc, fldAssembly); il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).FullName); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetType", new Type[] { typeof(string), typeof(bool) })); il.Emit(OpCodes.Stloc, fldType); il.Emit(OpCodes.Ldtoken, delegateType); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ldloc, fldType); il.Emit(OpCodes.Ldstr, "GetObject"); il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) })); il.Emit(OpCodes.Call, typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(MethodInfo) })); il.Emit(OpCodes.Castclass, delegateType); il.Emit(OpCodes.Stsfld, getObjectRef); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, fldArgs); il.Emit(OpCodes.Ldloc, fldArgs); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldtoken, typeBuilder); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Stelem_Ref); il.Emit(OpCodes.Ldloc, fldType); il.Emit(OpCodes.Ldstr, "EnsureComponentContextRegistryInitialized"); il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) })); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldloc, fldArgs); il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) })); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Leave_S, methodEnd); il.BeginCatchBlock(typeof(Exception)); il.Emit(OpCodes.Call, typeof(Trace).GetMethod("WriteLine", new Type[] { typeof(object) })); il.EndExceptionBlock(); il.MarkLabel(methodEnd); il.Emit(OpCodes.Ret); return(typeBuilder.CreateType()); }
public override void Generate (ILGenerator gen) { exp.GenerateSet (gen, new CodeAddOne (exp)); exp.Generate (gen); }
private static TypeBuilder CreateDynamicPropertyAccessor(Type _targetType, String mProperty) { Hashtable hashtable = getInitTypes(); TypeBuilder builder = getDynamicType(_targetType, mProperty); builder.AddInterfaceImplementation(typeof(IPropertyAccessor)); Type[] parameterTypes = new Type[] { typeof(Object) }; Type returnType = typeof(Object); ILGenerator iLGenerator = builder.DefineMethod("Get", MethodAttributes.Virtual | MethodAttributes.Public, returnType, parameterTypes).GetILGenerator(); MethodInfo method = _targetType.GetMethod("get_" + mProperty); if (method != null) { iLGenerator.DeclareLocal(typeof(Object)); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Castclass, _targetType); iLGenerator.EmitCall(OpCodes.Call, method, null); if (method.ReturnType.IsValueType) { iLGenerator.Emit(OpCodes.Box, method.ReturnType); } iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.Emit(OpCodes.Ldloc_0); } else { iLGenerator.ThrowException(typeof(MissingMethodException)); } iLGenerator.Emit(OpCodes.Ret); Type[] arrTypes = new Type[] { typeof(Object), typeof(Object) }; Type t = null; ILGenerator mGenerator = builder.DefineMethod("Set", MethodAttributes.Virtual | MethodAttributes.Public, t, arrTypes).GetILGenerator(); MethodInfo methodInfo = _targetType.GetMethod("set_" + mProperty); if (methodInfo != null) { Type parameterType = methodInfo.GetParameters()[0].ParameterType; mGenerator.DeclareLocal(parameterType); mGenerator.Emit(OpCodes.Ldarg_1); mGenerator.Emit(OpCodes.Castclass, _targetType); mGenerator.Emit(OpCodes.Ldarg_2); if (parameterType.IsValueType) { mGenerator.Emit(OpCodes.Unbox, parameterType); if (hashtable[parameterType] != null) { OpCode opcode = (OpCode)hashtable[parameterType]; mGenerator.Emit(opcode); } else { mGenerator.Emit(OpCodes.Ldobj, parameterType); } } else { mGenerator.Emit(OpCodes.Castclass, parameterType); } mGenerator.EmitCall(OpCodes.Callvirt, methodInfo, null); } else { mGenerator.ThrowException(typeof(MissingMethodException)); } mGenerator.Emit(OpCodes.Ret); return(_typeBuilder); }
public override void GenerateSet (ILGenerator gen, CodeExpression value) { exp.GenerateSet (gen, value); }
static void EmitOutParamPrep(ILGenerator ilg, LocalBuilder bufLocal, TypeInfo.TypeDescriptor type, int argnum) { ilg.Emit(OpCodes.Nop); ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13); ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldc_I4, 1); // PTR_IS_DATA ilg.Emit(OpCodes.Stind_I1); ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8); // offsetof(ptr) ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 0); // offsetof(val) ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Stind_I4); /* XXX 64-bitness! */ }
static void EmitComputeBufferLoc(ILGenerator ilg, LocalBuilder bufLocal, int argnum) { ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE); ilg.Emit(OpCodes.Add); }
public void FunctionDef(FunctionDef e) { Type[] param = new Type[e.Count]; DoVars = new Hashtable(); for (int i = 0; i < e.Count; i++){ param[i] = (Type)e.Params[i]; } //DescriptorInfo di = new DescriptorInfo(param); //di.SetReturnType(e.ExpType); //di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public; methodb = tb.DefineMethod(e.Name, MethodAttributes.Static | MethodAttributes.Public, e.ExpType, param); Functions.Add(e.Name, methodb); ILGenerator ilmain = il; il = methodb.GetILGenerator(); e.Body.Visit(this); il.Emit(OpCodes.Ret); il = ilmain; }
void Generate() { if (il == null) il = builder.GetILGenerator(); foreach (var i in instructions) i.Emit(il); }
// UnboxIfNeeded private static void UnboxIfNeeded(Type type, ILGenerator generator) { if (type.IsValueType) { generator.Emit(OpCodes.Unbox_Any, type); } }
void EmitOpCode(ILGenerator gen) { TypeSwitch( new Action<Empty>(v => gen.Emit(opCode)), new Action<IKMethod>(m => gen.Emit(opCode, m)), new Action<IKCtor>(ctor => gen.Emit(opCode, ctor)), new Action<IKType>(type => gen.Emit(opCode, type)), new Action<string>(str => gen.Emit(opCode, str)), new Action<long>(num => gen.Emit(opCode, num)), new Action<LocalBuilder>(lvar => gen.Emit(opCode, lvar)), new Action<Label>(label => gen.Emit(opCode, label)) ); }
static void EmitLoadReturnSlot_1(ILGenerator ilg, LocalBuilder bufLocal, int slotnum) { ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, (slotnum - 1) * VARIANT_SIZE); ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldind_I4); }
public EventLogger(object item) { if (item == null) { throw new ArgumentNullException("item"); } log = new EventLog(); Type itemType = item.GetType(); AssemblyName name = new AssemblyName(); name.Name = "EventLoggerAssembly"; AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); ModuleBuilder module = assembly.DefineDynamicModule("EventLoggerAssembly", "EventLoggerAssembly.dll"); Type ListType = log.GetType(); TypeBuilder logType = module.DefineType("Logger"); FieldBuilder logField = logType.DefineField("log", ListType, FieldAttributes.Public); ConstructorBuilder logCtor = logType.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type [] { ListType, typeof(object) }); logCtor.DefineParameter(1, ParameterAttributes.None, "test"); logCtor.DefineParameter(2, ParameterAttributes.None, "obj"); ILGenerator logIL = logCtor.GetILGenerator(); logIL.Emit(OpCodes.Ldarg_0); logIL.Emit(OpCodes.Ldarg_1); logIL.Emit(OpCodes.Stfld, logField); foreach (EventInfo Event in itemType.GetEvents()) { ILGenerator il; MethodInfo invoke = Event.EventHandlerType.GetMethod("Invoke"); MethodBuilder method = logType.DefineMethod(Event.Name, MethodAttributes.Public, null, new Type [] { invoke.GetParameters() [0].ParameterType, invoke.GetParameters() [1].ParameterType }); method.DefineParameter(1, ParameterAttributes.None, "test"); method.DefineParameter(2, ParameterAttributes.None, "test2"); il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, logField); il.Emit(OpCodes.Ldstr, Event.Name); il.Emit(OpCodes.Callvirt, ListType.GetMethod("Add")); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ret); logIL.Emit(OpCodes.Ldarg_2); logIL.Emit(OpCodes.Ldarg_0); logIL.Emit(OpCodes.Dup); logIL.Emit(OpCodes.Ldvirtftn, method); logIL.Emit(OpCodes.Newobj, Event.EventHandlerType.GetConstructor(new Type [] { typeof(object), typeof(IntPtr) })); logIL.Emit(OpCodes.Call, Event.GetAddMethod()); } logIL.Emit(OpCodes.Ret); Type builtLogType = logType.CreateType(); instance = builtLogType.GetConstructors() [0].Invoke(new object [] { log, item }); TestHelper.RemoveWarning(instance); //assembly.Save ("EventLoggerAssembly.dll"); }
static void EmitPtrAndFlagsStore(ILGenerator ilg, LocalBuilder bufLocal, int argnum, IntPtr ptr, sbyte flags) { //= bufLocal[argnum].ptr = ptr; ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8); ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldc_I4, ptr.ToInt32()); ilg.Emit(OpCodes.Stind_I4); //= bufLocal[argnum].flags = flags; ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13); ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Ldc_I4, (Int32)flags); ilg.Emit(OpCodes.Stind_I1); }
private void VerifyDeclareLocal(ILGenerator generator) { for (int i = 0; i < TestData.Length; i++) { LocalBuilder local = generator.DeclareLocal(TestData[i]); Assert.Equal(TestData[i], local.LocalType); Assert.Equal(i, local.LocalIndex); Assert.False(local.IsPinned); } }
private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex) { ParameterInfo[] args = method.GetParameters(); Label argsOk = generator.DefineLabel(); // throw an error if the number of argument values doesn't match method parameters generator.Emit(OpCodes.Ldarg, argsIndex); generator.Emit(OpCodes.Ldlen); generator.Emit(OpCodes.Ldc_I4, args.Length); generator.Emit(OpCodes.Beq, argsOk); generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes)); generator.Emit(OpCodes.Throw); generator.MarkLabel(argsOk); if (!method.IsConstructor && !method.IsStatic) { generator.PushInstance(method.DeclaringType); } int localVariableCount = 0; for (int i = 0; i < args.Length; i++) { ParameterInfo parameter = args[i]; Type parameterType = parameter.ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); LocalBuilder localVariable = generator.DeclareLocal(parameterType); // don't need to set variable for 'out' parameter if (!parameter.IsOut) { generator.PushArrayInstance(argsIndex, i); if (parameterType.IsValueType()) { Label skipSettingDefault = generator.DefineLabel(); Label finishedProcessingParameter = generator.DefineLabel(); // check if parameter is not null generator.Emit(OpCodes.Brtrue_S, skipSettingDefault); // parameter has no value, initialize to default generator.Emit(OpCodes.Ldloca_S, localVariable); generator.Emit(OpCodes.Initobj, parameterType); generator.Emit(OpCodes.Br_S, finishedProcessingParameter); // parameter has value, get value from array again and unbox and set to variable generator.MarkLabel(skipSettingDefault); generator.PushArrayInstance(argsIndex, i); generator.UnboxIfNeeded(parameterType); generator.Emit(OpCodes.Stloc, localVariableCount); // parameter finished, we out! generator.MarkLabel(finishedProcessingParameter); } else { generator.UnboxIfNeeded(parameterType); generator.Emit(OpCodes.Stloc, localVariableCount); } } generator.Emit(OpCodes.Ldloca_S, localVariable); localVariableCount++; } else if (parameterType.IsValueType()) { generator.PushArrayInstance(argsIndex, i); // have to check that value type parameters aren't null // otherwise they will error when unboxed Label skipSettingDefault = generator.DefineLabel(); Label finishedProcessingParameter = generator.DefineLabel(); // check if parameter is not null generator.Emit(OpCodes.Brtrue_S, skipSettingDefault); // parameter has no value, initialize to default LocalBuilder localVariable = generator.DeclareLocal(parameterType); generator.Emit(OpCodes.Ldloca_S, localVariable); generator.Emit(OpCodes.Initobj, parameterType); generator.Emit(OpCodes.Ldloc, localVariableCount); generator.Emit(OpCodes.Br_S, finishedProcessingParameter); // parameter has value, get value from array again and unbox generator.MarkLabel(skipSettingDefault); generator.PushArrayInstance(argsIndex, i); generator.UnboxIfNeeded(parameterType); // parameter finished, we out! generator.MarkLabel(finishedProcessingParameter); localVariableCount++; } else { generator.PushArrayInstance(argsIndex, i); generator.UnboxIfNeeded(parameterType); } } if (method.IsConstructor) { generator.Emit(OpCodes.Newobj, (ConstructorInfo)method); } else { generator.CallMethod((MethodInfo)method); } Type returnType = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType; if (returnType != typeof(void)) { generator.BoxIfNeeded(returnType); } else { generator.Emit(OpCodes.Ldnull); } generator.Return(); }
public void Generate(String filename) { AppDomain ad = Thread.GetDomain(); //AppDomain.CreateDomain("First", null, null); AssemblyName an = new AssemblyName(); an.Name = filename + ".exe"; //AssemblyName.CreateSimpleName(filename + ".exe", "LispExe", "Lisp Executable", "default_alias"); AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave); ModuleBuilder mb = ab.DefineDynamicModule(filename + ".exe", filename + ".exe"); MethodBuilder methodb; //DescriptorInfo di = new DescriptorInfo(0); tb = mb.DefineType(filename); //di.SetReturnType(typeof(void)); //di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public; methodb = tb.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), null); il = methodb.GetILGenerator(); do{ expr.Head.Visit(this); if (expr.Head is FunctionDef) GenerateDefStub(((FunctionDef)expr.Head).Name); else if (expr.Head is GlobalVarDef) GenerateDefStub(((GlobalVarDef)expr.Head).Name); else if (expr.Head.ExpType == typeof(int)) GenerateNumericExpStub(); else if (expr.Head.ExpType == typeof(bool)) GenerateBoolExpStub(); else if (expr.Head.ExpType == typeof(CList)) GenerateListExpStub(); expr = expr.Tail; }while(expr != null); il.Emit(OpCodes.Ret); tb.CreateType(); ab.SetEntryPoint((mb.GetType(filename)).GetMethod("Main")); ab.Save(filename + ".exe"); }
public void EmitMethodBody(ILGenerator il, MethodInfo method, int methodIndex, FieldInfo field) { Type actualReturnType; if (method.ReturnType == typeof(Task)) { actualReturnType = null; } else if (method.ReturnType.GetTypeInfo().IsGenericType&& method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>)) { actualReturnType = method.ReturnType.GenericTypeArguments[0]; } else { throw new ArgumentException("Only tasks are supported as return type.", method.ToString()); } var parameters = method.GetParameters(); il.DeclareLocal(typeof(object[])); il.DeclareLocal(typeof(InvocationInfo)); il.DeclareLocal(typeof(MethodInfo)); //load all parameters in object[] PushArguments(parameters, il); //load the method il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, _getMethods); il.Emit(OpCodes.Ldc_I4, methodIndex); il.Emit(OpCodes.Ldelem_Ref); //load array[index] il.Emit(OpCodes.Stloc_2); //new InvocationInfo(method, object[]) il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Newobj, _invocationInfoCtor); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, _getInterceptor); il.Emit(OpCodes.Ldloc_1); var interceptionMethod = actualReturnType == null ? _asyncHandlerMethod : _asyncHandlerMethodGeneric.MakeGenericMethod(actualReturnType); il.Emit(OpCodes.Callvirt, interceptionMethod); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Call, _invocationReturn); if (actualReturnType != null) { il.Emit(OpCodes.Castclass, method.ReturnType); } il.Emit(OpCodes.Ret); }
internal void Bake() { this.signature = this.ModuleBuilder.GetSignatureBlobIndex(this.MethodSignature); if (ilgen != null) { if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000)); } rva = ilgen.WriteBody(initLocals); if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.CloseMethod(); } ilgen = null; } else { rva = -1; } if (declarativeSecurity != null) { this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity); } }
abstract public void BuildAssembly(ILGenerator il);
public void DeclareLocals(ILGenerator ilg) { foreach (string local in Locals) { Type t; if (!ILReader2.TryGetType(local, out t)) break; ilg.DeclareLocal(t); } }
public static void Main() { // Get the assembly that contains the Timer type (Sytem.dll). // The following code uses the fact that System.dll has the // same public key as mscorlib.dll to construct a string // representing the full assembly name. string fullName = ""; foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies()) { if (assem.GetName().Name == "mscorlib") { fullName = assem.FullName; } } Assembly sys = Assembly.Load("System" + fullName.Substring(fullName.IndexOf(","))); // Get a Type object representing the Timer type. Type t = sys.GetType("System.Timers.Timer"); // Create an instance of the Timer type. timer = Activator.CreateInstance(t); // Use reflection to get the Elapsed event. EventInfo eInfo = t.GetEvent("Elapsed"); // In order to create a method to handle the Elapsed event, // it is necessary to know the signature of the delegate // used to raise the event. Reflection.Emit can then be // used to construct a dynamic class with a static method // that has the correct signature. // Get the event handler type of the Elapsed event. This is // a delegate type, so it has an Invoke method that has // the same signature as the delegate. The following code // creates an array of Type objects that represent the // parameter types of the Invoke method. // Type handlerType = eInfo.EventHandlerType; MethodInfo invokeMethod = handlerType.GetMethod("Invoke"); ParameterInfo[] parms = invokeMethod.GetParameters(); Type[] parmTypes = new Type[parms.Length]; for (int i = 0; i < parms.Length; i++) { parmTypes[i] = parms[i].ParameterType; } // Use Reflection.Emit to create a dynamic assembly that // will be run but not saved. An assembly must have at // least one module, which in this case contains a single // type. The only purpose of this type is to contain the // event handler method. (In the .NET Framework version // 2.0 you can use dynamic methods, which are simpler // because there is no need to create an assembly, module, // or type.) AssemblyName aName = new AssemblyName(); aName.Name = "DynamicTypes"; AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run); ModuleBuilder mb = ab.DefineDynamicModule(aName.Name); TypeBuilder tb = mb.DefineType("Handler", TypeAttributes.Class | TypeAttributes.Public); // Create the method that will handle the event. The name // is not important. The method is static, because there is // no reason to create an instance of the dynamic type. // // The parameter types and return type of the method are // the same as those of the delegate's Invoke method, // captured earlier. MethodBuilder handler = tb.DefineMethod("DynamicHandler", MethodAttributes.Public | MethodAttributes.Static, invokeMethod.ReturnType, parmTypes); // Generate code to handle the event. In this case, the // handler simply prints a text string to the console. // ILGenerator il = handler.GetILGenerator(); il.EmitWriteLine("Timer's Elapsed event is raised."); il.Emit(OpCodes.Ret); // CreateType must be called before the Handler type can // be used. In order to create the delegate that will // handle the event, a MethodInfo from the finished type // is required. Type finished = tb.CreateType(); MethodInfo eventHandler = finished.GetMethod("DynamicHandler"); // Use the MethodInfo to create a delegate of the correct // type, and call the AddEventHandler method to hook up // the event. Delegate d = Delegate.CreateDelegate(handlerType, eventHandler); eInfo.AddEventHandler(timer, d); // Late-bound calls to the Interval and Enabled property // are required to enable the timer with a one-second // interval. t.InvokeMember("Interval", BindingFlags.SetProperty, null, timer, new Object[] { 1000 }); t.InvokeMember("Enabled", BindingFlags.SetProperty, null, timer, new Object[] { true }); Console.WriteLine("Press the Enter key to end the program."); Console.ReadLine(); }
static Converter() { _type = typeof(T); TypeInfo typeInfo = _type.GetTypeInfo(); if (_type == typeof(string)) { _writeAction = (Converter.WriteAction <T>)(Delegate) new Converter.WriteAction <string>(StringConverter.Write); _readAction = (Converter.ReadAction <T>)(Delegate) new Converter.ReadAction <string>(StringConverter.Read); } else if (typeInfo.IsArray) { Type elementType = typeInfo.GetElementType(); _writeAction = (Converter.WriteAction <T>) typeof(Converter <>).MakeGenericType(elementType).GetTypeInfo().GetDeclaredMethod(nameof(WriteArray)).CreateDelegate(typeof(Converter.WriteAction <T>)); _readAction = (Converter.ReadAction <T>) typeof(Converter <>).MakeGenericType(elementType).GetTypeInfo().GetDeclaredMethod(nameof(ReadArray)).CreateDelegate(typeof(Converter.ReadAction <T>)); } else { try { if (typeInfo.IsUnmanaged()) { TypeInfo unmanagedType = typeof(UnmanagedConverter <>).MakeGenericType(_type).GetTypeInfo(); _writeAction = (Converter.WriteAction <T>)unmanagedType.GetDeclaredMethod(nameof(UnmanagedConverter <bool> .Write)).CreateDelegate(typeof(Converter.WriteAction <T>)); _readAction = (Converter.ReadAction <T>)unmanagedType.GetDeclaredMethod(nameof(UnmanagedConverter <bool> .Read)).CreateDelegate(typeof(Converter.ReadAction <T>)); } else { DynamicMethod writeMethod = new DynamicMethod($"Write_{nameof(T)}", typeof(void), new[] { _type.MakeByRefType(), typeof(Stream), typeof(byte[]), typeof(byte *) }, typeof(Converter <T>), true); ILGenerator writeGenerator = writeMethod.GetILGenerator(); DynamicMethod readMethod = new DynamicMethod($"Read_{nameof(T)}", _type, new[] { typeof(Stream), typeof(byte[]), typeof(byte *) }, typeof(Converter <T>), true); ILGenerator readGenerator = readMethod.GetILGenerator(); LocalBuilder readValue = readGenerator.DeclareLocal(_type); if (typeInfo.IsClass) { readGenerator.Emit(OpCodes.Ldsfld, typeof(Converter <T>).GetTypeInfo().GetDeclaredField(nameof(_type))); readGenerator.Emit(OpCodes.Call, typeof(ObjectInitializer).GetTypeInfo().GetDeclaredMethod(nameof(ObjectInitializer.Create))); readGenerator.Emit(OpCodes.Stloc, readValue); } else { readGenerator.Emit(OpCodes.Ldloca_S, readValue); readGenerator.Emit(OpCodes.Initobj, _type); } while (typeInfo != null) { foreach (FieldInfo fieldInfo in typeInfo.DeclaredFields.Where(f => !f.IsStatic)) { writeGenerator.Emit(OpCodes.Ldarg_0); if (typeInfo.IsClass) { writeGenerator.Emit(OpCodes.Ldind_Ref); } writeGenerator.Emit(OpCodes.Ldflda, fieldInfo); writeGenerator.Emit(OpCodes.Ldarg_1); writeGenerator.Emit(OpCodes.Ldarg_2); writeGenerator.Emit(OpCodes.Ldarg_3); writeGenerator.Emit(OpCodes.Call, typeof(Converter <>).MakeGenericType(fieldInfo.FieldType).GetTypeInfo().GetDeclaredMethod(nameof(Converter <T> .Write))); readGenerator.Emit(typeInfo.IsClass ? OpCodes.Ldloc : OpCodes.Ldloca_S, readValue); readGenerator.Emit(OpCodes.Ldarg_0); readGenerator.Emit(OpCodes.Ldarg_1); readGenerator.Emit(OpCodes.Ldarg_2); readGenerator.Emit(OpCodes.Call, typeof(Converter <>).MakeGenericType(fieldInfo.FieldType).GetTypeInfo().GetDeclaredMethod(nameof(Converter <T> .Read))); readGenerator.Emit(OpCodes.Stfld, fieldInfo); } typeInfo = typeInfo.BaseType?.GetTypeInfo(); } writeGenerator.Emit(OpCodes.Ret); _writeAction = (Converter.WriteAction <T>)writeMethod.CreateDelegate(typeof(Converter.WriteAction <T>)); readGenerator.Emit(OpCodes.Ldloc, readValue); readGenerator.Emit(OpCodes.Ret); _readAction = (Converter.ReadAction <T>)readMethod.CreateDelegate(typeof(Converter.ReadAction <T>)); } } catch { _writeAction = (in T _, Stream __, byte[] ___, byte *____) => throw new InvalidOperationException($"Unable to handle type {_type.FullName}"); _readAction = (_, __, ___) => throw new InvalidOperationException($"Unable to handle type {_type.FullName}"); } } }
private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { List <CodeInstruction> newInstructions = ListPool <CodeInstruction> .Shared.Rent(instructions); int offset = -6; int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ret) + offset; Label returnLabel = generator.DefineLabel(); newInstructions.InsertRange(index, new CodeInstruction[] { // Player.Get(ReferenceHub); new(OpCodes.Ldarg_0), new(OpCodes.Ldfld, Field(typeof(InventorySystem.Inventory), nameof(InventorySystem.Inventory._hub))), new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), // ammoType new(OpCodes.Ldarg_1), // amount new(OpCodes.Ldarg_2), // var ev = DroppingAmmoEventArgs(...) new(OpCodes.Ldc_I4_1), new(OpCodes.Newobj, GetDeclaredConstructors(typeof(DroppingAmmoEventArgs))[0]), new(OpCodes.Dup), // Player.OnDroppingAmmo(ev); new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnDroppingAmmo))), // if (!ev.IsAllowed) return; new(OpCodes.Callvirt, PropertyGetter(typeof(DroppingAmmoEventArgs), nameof(DroppingAmmoEventArgs.IsAllowed))), new(OpCodes.Brfalse_S, returnLabel), });
public void __ReleaseILGenerator() { if (ilgen != null) { if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000)); } rva = ilgen.WriteBody(initLocals); if (this.ModuleBuilder.symbolWriter != null) { this.ModuleBuilder.symbolWriter.CloseMethod(); } ilgen = null; } }
private void GenStmt(Stmt stmt, ILGenerator il, Type[] argtypes) { if (stmt is VarDeclaration) { VarDeclaration var = (VarDeclaration)stmt; string tname = var.Type.GetTypeName(); if (typeTable.ContainsKey(tname)) { TypeBuilder typeBuilder = typeTable[tname]; ConstructorBuilder ctorBuilder = ctorTable[tname]; LocalBuilder localBuilder = il.DeclareLocal(typeBuilder); symbolTable[var.Name] = localBuilder; il.Emit(OpCodes.Newobj, ctorBuilder); il.Emit(OpCodes.Stloc, localBuilder); } else { Type vtype = var.Type.GetAType(); symbolTable[var.Name] = il.DeclareLocal(vtype); GenExpr(var.Expr, TypeOfExpr(var.Expr, argtypes), il, argtypes); Store(var.Name, TypeOfExpr(var.Expr, argtypes), il); } } else if (stmt is Assign) { Assign assign = (Assign)stmt; GenExpr(assign.Expr, TypeOfExpr(assign.Expr, argtypes), il, argtypes); Store(assign.Name, TypeOfExpr(assign.Expr, argtypes), il); } else if (stmt is ExprStmt) { Expr expr = ((ExprStmt)stmt).Expr; if (expr is FuncCall) { FuncCall funcCall = (FuncCall)expr; if (funcCall.Name.Count > 1 && funcCall.Name[0] != "System") { if (symbolTable.ContainsKey(funcCall.Name[0])) { LocalBuilder localBuilder = (LocalBuilder)symbolTable[funcCall.Name[0]]; il.Emit(OpCodes.Ldloc, localBuilder); } } Type[] typeArgs = new Type[funcCall.Args.Count]; for (int i = 0; i < funcCall.Args.Count; i++) { typeArgs[i] = TypeOfExpr(funcCall.Args[i], argtypes); GenExpr(funcCall.Args[i], typeArgs[i], il, argtypes); } string strFunc = funcCall.Name[funcCall.Name.Count - 1]; // "WriteLine" if (funcCall.Name[0] == "System") { string strType = funcCall.Name[0]; for (int i = 1; i < funcCall.Name.Count - 1; i++) { strType += "." + funcCall.Name[i]; } Type typeFunc = Type.GetType(strType); // System.Console il.Emit(OpCodes.Call, typeFunc.GetMethod(strFunc, typeArgs)); } else if (funcCall.Name.Count > 1) { MethodBuilder methodBuilder = funcTable[strFunc]; il.EmitCall(OpCodes.Call, methodBuilder, null); } else { if (!funcTable.ContainsKey(strFunc)) { throw new Exception("undeclared function '" + strFunc + "'"); } MethodBuilder funcBuilder = funcTable[strFunc]; il.EmitCall(OpCodes.Call, funcBuilder, null); } } } }