private static void EnsureCount(EmittingContext context, GroboIL.Local list, GroboIL.Local index, Type type) { var il = context.Il; if (context.SkipVisibility) { il.Ldloc(list); // stack: [list] il.Ldloc(index); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Call(type.GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)); // list.EnsureCapacity(arrayIndex + 1); stack: [] il.Ldloc(list); // stack: [list] il.Ldloc(index); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Stfld(type.GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic)); // list.Count = arrayIndex + 1; stack: [] } else { // todo убрать Reflection var resizer = (Tuple <Delegate, IntPtr>)resizeListMethod.MakeGenericMethod(type.GetGenericArguments()[0]).Invoke(null, new object[0]); il.Ldloc(list); il.Ldloc(index); il.Ldc_IntPtr(resizer.Item2); il.Calli(CallingConventions.Standard, typeof(void), new[] { type, typeof(int) }); } }
public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, GroboIL.Local typeSize) { il.Ldloc(offset); il.Ldloc(typeSize); il.Add(); il.Stloc(offset); }
public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, int len) { il.Ldloc(offset); il.Ldc_I4(len); il.Add(); il.Stloc(offset); }
public static void ReadObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldelem(typeof(byte)); WriteOffsetAppend(il, offset, 1); il.Brtrue(finishMethod); }
private static void EmitXPlusPlus(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Dup(); il.Ldc_I4(1); il.Add(); il.Stloc(intLocal); }
private static void EmitMinusMinusX(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Ldc_I4(1); il.Sub(); il.Dup(); il.Stloc(intLocal); }
public static void WriteSizeChecker(GroboIL il, GroboIL.Local buffer, GroboIL.Local offset, int len) { //il.Ldloca(buffer); //il.Ldloc(offset); //il.Ldc_I4(len); //il.Call(resizeMethod); il.Ldc_I4(len); Resize(il, buffer, offset); }
public CompilerVisitor(GroboIL generator, ErrorSink errors) { this.Generator = generator ?? throw new ArgumentNullException(nameof(generator)); this.RawGenerator = (ILGenerator)typeof(GroboIL).GetField("il", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(generator); Temp1 = generator.DeclareLocal(typeof(BitsValue), "temp1"); Temp2 = generator.DeclareLocal(typeof(ulong), "temp2"); RegisterFunctions(); }
public static void CompileWriter(BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { if (bs.PropertyList.Count > 0) { foreach (var item in bs.PropertyList) { ProcessWrite(item, bs, il, binaryStruct, value, buffer, offset, typeSize); } return; } }
public static void WriteObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { var _null = il.DeclareLocal(typeof(bool)); il.Ldnull(); il.Ceq(); il.Stloc(_null); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(_null); il.Stelem(typeof(byte)); WriteOffsetAppend(il, offset, 1); il.Ldloc(_null); il.Brtrue(finishMethod); }
public static void CompileReader(BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local result, GroboIL.Local typeSize) { if (bs.PropertyList.Count > 0) { foreach (var item in bs.PropertyList) { if (item.IsBaseType) { item.BinaryType.GetReadILCode(item, bs, il, binaryStruct, buffer, result, typeSize, offset, false); continue; } var methodBreak = il.DefineLabel("breakReadMethod"); ReadObjectNull(il, methodBreak, buffer, offset, typeSize); var in_value = il.DeclareLocal(item.PropertyInfo.PropertyType); var constr = BinaryStruct.GetConstructor(item.PropertyInfo.PropertyType, null); if (constr == null) { throw new Exception($"Type {item.PropertyInfo.PropertyType} not have constructor with not parameters"); } il.Newobj(constr); il.Stloc(in_value); CompileReader(item.BinaryStruct, il, binaryStruct, buffer, offset, in_value, typeSize); il.Ldloc(result); il.Ldloc(in_value); il.Call(item.Setter, isVirtual: true); il.MarkLabel(methodBreak); //il.Pop(); } } }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var r = il.DeclareLocal(typeof(DateTime)); var v = il.DeclareLocal(typeof(double)); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Stloc(v); il.Ldloca(r); il.Ldc_I4(1970); il.Ldc_I4(1); il.Ldc_I4(1); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Call(datetimeConstructor); il.Ldloca(r); il.Ldloc(v); il.Call(addMethod); if (listValue) { il.Stloc(result); } else { il.Stloc(r); } BinaryStruct.WriteOffsetAppend(il, offset, 8); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
public LocalHolder(EmittingContext owner, Type type, GroboIL.Local local) { this.owner = owner; this.type = type; this.local = local; }
public void FreeLocal(Type type, GroboIL.Local local) { locals[type].Enqueue(local); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 2); var arr = il.DeclareLocal(typeof(byte[])); il.Ldloc(value); if (!listValue) { il.Call(prop.Getter); } il.Dup(); il.Pop(); il.Call(writeBitConverterMethodInfo); il.Stloc(arr); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arr); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 2; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arr); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 2); }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var r = il.DeclareLocal(typeof(short)); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); if (listValue) { il.Stloc(result); } else { il.Stloc(r); } BinaryStruct.WriteOffsetAppend(il, offset, 2); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 5); var arr = il.DeclareLocal(typeof(byte[])); var arrSize = il.DeclareLocal(typeof(byte[])); var temp = il.DeclareLocal(typeof(string)); var exitLabel = il.DefineLabel("exit"); il.Ldloc(value); if (!listValue) { il.Call(prop.Getter); } il.Stloc(temp); il.Ldloc(temp); BinaryStruct.WriteObjectNull(il, exitLabel, buffer, offset, typeSize); il.Ldloc(temp); il.Call(typeof(string).GetProperty("Length").GetMethod); il.Stloc(typeSize); il.Ldarg(1); il.Call(codingMethodInfo); il.Ldloc(temp); il.Call(currentStruct.Coding.GetType().GetMethod("GetBytes", new Type[] { typeof(string) })); il.Stloc(arr); il.Ldloc(arr); il.Call(typeof(byte[]).GetProperty("Length").GetMethod); il.Stloc(typeSize); il.Ldloc(typeSize); il.Call(writeBitConverterMethodInfo); il.Stloc(arrSize); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arrSize); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 4; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arrSize); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 4); il.Ldloc(typeSize); il.Ldc_I4(0); il.Ceq(); il.Brtrue(exitLabel); BinaryStruct.WriteSizeChecker(il, buffer, offset, typeSize); var ivar = il.DeclareLocal(typeof(int)); var point = il.DefineLabel("for_label"); il.Ldc_I4(0); il.Stloc(ivar); il.MarkLabel(point); //body il.Ldloc(buffer); il.Ldloc(ivar); il.Ldloc(offset); il.Add(); il.Ldloc(arr); il.Ldloc(ivar); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); //end body il.Ldc_I4(1); il.Ldloc(ivar); il.Add(); il.Stloc(ivar); il.Ldloc(ivar); il.Ldloc(typeSize); il.Clt(false); il.Brtrue(point); BinaryStruct.WriteOffsetAppend(il, offset, typeSize); il.MarkLabel(exitLabel); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { var arr = il.DeclareLocal(prop.PropertyInfo.PropertyType); var len = il.DeclareLocal(typeof(int)); if (prop.PropertyInfo != null) { il.Ldloc(value); il.Call(prop.ArraySizeProperty.Getter); il.Stloc(len); } else { il.Ldc_I4(prop.ArraySize); il.Stloc(len); } il.Ldloc(value); il.Call(prop.Getter); il.Stloc(arr); var typeKey = prop.PropertyInfo.PropertyType.GetGenericArguments()[0]; var typeValue = prop.PropertyInfo.PropertyType.GetGenericArguments()[1]; var ivar = il.DeclareLocal(typeof(int)); var currentItemKey = il.DeclareLocal(typeKey); var currentItemValue = il.DeclareLocal(typeValue); var point = il.DefineLabel("for_label"); il.Ldc_I4(0); il.Stloc(ivar); var enumeratorMethod = prop.PropertyInfo.PropertyType.GetMethod("GetEnumerator"); var enumerator = il.DeclareLocal(enumeratorMethod.ReturnType); var moveNext = enumerator.Type.GetMethod("MoveNext"); var getCurrent = enumerator.Type.GetMethod("get_Current"); var temp = il.DeclareLocal(getCurrent.ReturnType); var exist = il.DeclareLocal(typeof(bool)); il.Ldloc(arr); il.Call(enumeratorMethod, isVirtual: true); il.Stloc(enumerator); var keyGetter = getCurrent.ReturnType.GetMethod("get_Key"); var valueGetter = getCurrent.ReturnType.GetMethod("get_Value"); il.MarkLabel(point); //body il.Ldloca(enumerator); il.Call(moveNext, enumerator.Type); il.Stloc(exist); il.Ldloca(enumerator); //il.Calli(CallingConventions.Any, typeof(KeyValuePair<int, int>),new Type[] { typeof(int),typeof(int) }); il.Call(getCurrent, enumerator.Type); il.Stloc(temp); il.Ldloca(temp); il.Call(keyGetter, typeof(int)); il.Stloc(currentItemKey); if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[0])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[0]); t.GetWriteILCode(prop, currentStruct, il, binaryStruct, currentItemKey, typeSize, buffer, offset, true); } else { BinaryStruct.CompileWriter(currentStruct.CurrentStorage.GetTypeInfo(typeKey, currentStruct.Scheme), il, binaryStruct, currentItemKey, buffer, offset, typeSize); } il.Ldloca(temp); il.Call(valueGetter); il.Stloc(currentItemValue); if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[1])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[1]); t.GetWriteILCode(prop, currentStruct, il, binaryStruct, currentItemValue, typeSize, buffer, offset, true); } else { BinaryStruct.CompileWriter(currentStruct.CurrentStorage.GetTypeInfo(typeValue, currentStruct.Scheme), il, binaryStruct, currentItemValue, buffer, offset, typeSize); } //end body il.Ldc_I4(1); il.Ldloc(ivar); il.Add(); il.Stloc(ivar); il.Ldloc(ivar); il.Ldloc(len); il.Clt(false); il.Brtrue(point); }
public void Test2() { AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "AdderExceptionAsm"; // Create dynamic assembly. AppDomain myAppDomain = Thread.GetDomain(); AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave); // Create a dynamic module. ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod", true); var symbolDocumentWriter = myModuleBuilder.GetSymWriter().DefineDocument("AdderException.cil", Guid.Empty, Guid.Empty, Guid.Empty); TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder"); Type[] adderParams = { typeof(int), typeof(int) }; ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor(new[] { typeof(string) }); MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString"); MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }); // Define method to add two numbers. MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), adderParams); using (var il = new GroboIL(myMethodBuilder, symbolDocumentWriter)) { // Declare local variable. GroboIL.Local myLocalBuilder1 = il.DeclareLocal(typeof(int)); GroboIL.Local myLocalBuilder2 = il.DeclareLocal(typeof(OverflowException)); // Define label. GroboIL.Label myFailedLabel = il.DefineLabel("failed"); GroboIL.Label myEndOfMethodLabel = il.DefineLabel("end"); // Begin exception block. il.BeginExceptionBlock(); il.Ldarg(0); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(1); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); il.Stloc(myLocalBuilder1); il.Leave(myEndOfMethodLabel); il.MarkLabel(myFailedLabel); il.Ldstr("Cannot accept values over 10 for add."); il.Newobj(myConstructorInfo); il.Stloc(myLocalBuilder2); il.Ldloc(myLocalBuilder2); // Throw the exception. il.Throw(); // Call 'BeginExceptFilterBlock'. il.BeginExceptFilterBlock(); il.WriteLine("Except filter block called."); // Call catch block. il.BeginCatchBlock(null); // Call other catch block. il.BeginCatchBlock(typeof(OverflowException)); il.Ldstr("{0}"); il.Ldloc(myLocalBuilder2); il.Call(myExToStrMI); il.Call(myWriteLineMI); il.Ldc_I4(-1); il.Stloc(myLocalBuilder1); // Call finally block. il.BeginFinallyBlock(); il.WriteLine("Finally block called."); // End the exception block. il.EndExceptionBlock(); il.MarkLabel(myEndOfMethodLabel); il.Ldloc(myLocalBuilder1); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 8); var arr = il.DeclareLocal(typeof(byte[])); var v = il.DeclareLocal(typeof(DateTime)); var t = il.DeclareLocal(typeof(TimeSpan)); if (!listValue) { il.Ldloc(value); var v1 = il.DeclareLocal(typeof(DateTime)); il.Call(prop.Getter); il.Stloc(v1); il.Ldloca(v1); } else { il.Ldloca(value); } il.Ldloca(v); il.Ldc_I4(1970); il.Ldc_I4(1); il.Ldc_I4(1); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Call(datetimeConstructor); il.Ldloc(v); il.Call(substractMethod); il.Stloc(t); il.Ldloca(t); il.Call(propertyGetter); il.Call(writeBitConverterMethodInfo); il.Stloc(arr); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arr); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 8; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arr); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 8); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 1); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(value); if (!listValue) { il.Call(prop.Getter); } il.Stelem(typeof(byte)); BinaryStruct.WriteOffsetAppend(il, offset, 1); }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var r = il.DeclareLocal(typeof(Vector2)); if (listValue) { il.Ldloca(result); } else { il.Ldloca(r); } il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(4); il.Add(); il.Call(readBitConverterMethodInfo); il.Call(initialConstructor); //if (listValue) // il.Stloc(result); //else // il.Stloc(r); BinaryStruct.WriteOffsetAppend(il, offset, 8); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { var arr = il.DeclareLocal(prop.PropertyInfo.PropertyType); il.Ldloc(value); il.Call(prop.Getter); il.Stloc(arr); var exitLabel = il.DefineLabel("exit"); BinaryStruct.WriteSizeChecker(il, buffer, offset, 5); BinaryStruct.WriteObjectNull(il, exitLabel, arr, buffer, offset, typeSize); var arrSize = il.DeclareLocal(typeof(byte[])); var len = il.DeclareLocal(typeof(int)); il.Ldloc(value); il.Call(prop.Getter); il.Call(typeof(ICollection).GetProperty("Count").GetMethod); il.Stloc(len); il.Ldloc(len); il.Call(writeBitConverterMethodInfo); il.Stloc(arrSize); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arrSize); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 4; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arrSize); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 4); il.Ldloc(len); il.Ldc_I4(0); il.Ceq(); il.Brtrue(exitLabel); var type = prop.PropertyInfo.PropertyType.GetElementType(); var ivar = il.DeclareLocal(typeof(int)); var currentValue = il.DeclareLocal(type); var point = il.DefineLabel("for_label"); il.Ldc_I4(0); il.Stloc(ivar); il.MarkLabel(point); //body il.Ldloc(arr); il.Ldloc(ivar); il.Ldelem(type); //il.Call(prop.PropertyInfo.PropertyType.GetMethod("Get"), isVirtual: true); il.Stloc(currentValue); if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[0])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[0]); t.GetWriteILCode(prop, currentStruct, il, binaryStruct, currentValue, typeSize, buffer, offset, true); } else { BinaryStruct.CompileWriter(currentStruct.CurrentStorage.GetTypeInfo(type, currentStruct.Scheme), il, binaryStruct, currentValue, buffer, offset, typeSize); } //end body il.Ldc_I4(1); il.Ldloc(ivar); il.Add(); il.Stloc(ivar); il.Ldloc(ivar); il.Ldloc(len); il.Clt(false); il.Brtrue(point); il.MarkLabel(exitLabel); }
private static void EmitLoadArrayItemRef(this GroboIL il, GroboIL.Local arrayLocal, GroboIL.Local indexLocal, Type elementType) { il.Ldloc(arrayLocal); il.Ldloc(indexLocal); il.Ldelema(elementType); }
public void Test1() { var overflow = typeof(OverflowException); var exCtorInfo = overflow.GetConstructor(new[] { typeof(string) }); var exToStrMI = overflow.GetMethod("ToString"); var writeLineMI = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(TestTryCatch)); using (var il = new GroboIL(method)) { GroboIL.Local tmp1 = il.DeclareLocal(typeof(int)); GroboIL.Local tmp2 = il.DeclareLocal(overflow); // In order to successfully branch, we need to create labels // representing the offset IL instruction block to branch to. // These labels, when the MarkLabel(Label) method is invoked, // will specify the IL instruction to branch to. // GroboIL.Label failed = il.DefineLabel("failed"); GroboIL.Label endOfMthd = il.DefineLabel("end"); // Begin the try block. il.BeginExceptionBlock(); // First, load argument 0 and the integer value of "100" onto the // stack. If arg0 > 100, branch to the label "failed", which is marked // as the address of the block that throws an exception. // il.Ldarg(0); il.Ldc_I4(100); il.Bgt(failed, false); // Now, check to see if argument 1 was greater than 100. If it was, // branch to "failed." Otherwise, fall through and perform the addition, // branching unconditionally to the instruction at the label "endOfMthd". // il.Ldarg(1); il.Ldc_I4(100); il.Bgt(failed, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); // Store the result of the addition. il.Stloc(tmp1); il.Leave(endOfMthd); // If one of the arguments was greater than 100, we need to throw an // exception. We'll use "OverflowException" with a customized message. // First, we load our message onto the stack, and then create a new // exception object using the constructor overload that accepts a // string message. // il.MarkLabel(failed); il.Ldstr("Cannot accept values over 100 for add."); il.Newobj(exCtorInfo); // We're going to need to refer to that exception object later, so let's // store it in a temporary variable. Since the store function pops the // the value/reference off the stack, and we'll need it to throw the // exception, we will subsequently load it back onto the stack as well. il.Stloc(tmp2); il.Ldloc(tmp2); // Throw the exception now on the stack. il.Throw(); // Start the catch block for OverflowException. // il.BeginCatchBlock(overflow); // When we enter the catch block, the thrown exception // is on the stack. Store it, then load the format string // for WriteLine. // il.Stloc(tmp2); il.Ldstr("Caught {0}"); // Push the thrown exception back on the stack, then // call its ToString() method. Note that if this catch block // were for a more general exception type, like Exception, // it would be necessary to use the ToString for that type. // il.Ldloc(tmp2); il.Call(exToStrMI); // The format string and the return value from ToString() are // now on the stack. Call WriteLine(string, object). // il.Call(writeLineMI); // Since our function has to return an integer value, we'll load -1 onto // the stack to indicate an error, and store it in local variable tmp1. // il.Ldc_I4(-1); il.Stloc(tmp1); // End the exception handling block. il.EndExceptionBlock(); // The end of the method. If no exception was thrown, the correct value // will be saved in tmp1. If an exception was thrown, tmp1 will be equal // to -1. Either way, we'll load the value of tmp1 onto the stack and return. // il.MarkLabel(endOfMthd); il.Ldloc(tmp1); il.Ret(); Console.WriteLine(il.GetILCode()); } }
private static void EmitSetIntToZero(this GroboIL il, GroboIL.Local intLocal) { il.Ldc_I4(0); il.Stloc(intLocal); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { var arr = il.DeclareLocal(prop.PropertyInfo.PropertyType); var len = il.DeclareLocal(typeof(int)); if (prop.PropertyInfo != null) { il.Ldloc(value); il.Call(prop.ArraySizeProperty.Getter); il.Stloc(len); } else { il.Ldc_I4(prop.ArraySize); il.Stloc(len); } il.Ldloc(value); il.Call(prop.Getter); il.Stloc(arr); var type = prop.PropertyInfo.PropertyType.GetGenericArguments()[0]; var ivar = il.DeclareLocal(typeof(int)); var currentValue = il.DeclareLocal(type); var point = il.DefineLabel("for_label"); il.Ldc_I4(0); il.Stloc(ivar); il.MarkLabel(point); //body il.Ldloc(arr); il.Ldloc(ivar); il.Call(prop.PropertyInfo.PropertyType.GetMethod("get_Item"), isVirtual: true); il.Stloc(currentValue); if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[0])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[0]); t.GetWriteILCode(prop, currentStruct, il, binaryStruct, currentValue, typeSize, buffer, offset, true); } else { BinaryStruct.CompileWriter(currentStruct.CurrentStorage.GetTypeInfo(type, currentStruct.Scheme), il, binaryStruct, currentValue, buffer, offset, typeSize); } //end body il.Ldc_I4(1); il.Ldloc(ivar); il.Add(); il.Stloc(ivar); il.Ldloc(ivar); il.Ldloc(len); il.Clt(false); il.Brtrue(point); }
public LocalILInstructionParameter(GroboIL.Local local) { Local = local; }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var exitLabel = il.DefineLabel("exit"); BinaryStruct.ReadObjectNull(il, exitLabel, buffer, offset, typeSize); var len = il.DeclareLocal(typeof(int)); var list = il.DeclareLocal(prop.PropertyInfo.PropertyType); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Stloc(len); BinaryStruct.WriteOffsetAppend(il, offset, 4); il.Newobj(BinaryStruct.GetConstructor(prop.PropertyInfo.PropertyType, null)); il.Stloc(list); il.Ldloc(result); il.Ldloc(list); il.Call(prop.Setter, isVirtual: true); il.Ldloc(len); il.Ldc_I4(0); il.Ceq(); il.Brtrue(exitLabel); var typeKey = prop.PropertyInfo.PropertyType.GetGenericArguments()[0]; var typeValue = prop.PropertyInfo.PropertyType.GetGenericArguments()[1]; var ivar = il.DeclareLocal(typeof(int)); var currentItemKey = il.DeclareLocal(typeKey); var currentItemValue = il.DeclareLocal(typeValue); var point = il.DefineLabel("for_label"); il.Ldc_I4(0); il.Stloc(ivar); il.MarkLabel(point); //body //key if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[0])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[0]); t.GetReadILCode(prop, currentStruct, il, binaryStruct, buffer, currentItemKey, typeSize, offset, true); } else { var constr = BinaryStruct.GetConstructor(typeKey, null); if (constr == null) { throw new Exception($"Type {typeKey} not have constructor with not parameters"); } il.Newobj(constr); il.Stloc(currentItemKey); BinaryStruct.CompileReader(currentStruct.CurrentStorage.GetTypeInfo(typeKey, currentStruct.Scheme), il, binaryStruct, buffer, offset, currentItemKey, typeSize); } //value if (typeof(IBasicType).IsAssignableFrom(prop.BinaryAttr.Type.GetGenericArguments()[1])) { IBasicType t = (IBasicType)Activator.CreateInstance(prop.BinaryAttr.Type.GetGenericArguments()[1]); t.GetReadILCode(prop, currentStruct, il, binaryStruct, buffer, currentItemValue, typeSize, offset, true); } else { var constr = BinaryStruct.GetConstructor(typeValue, null); if (constr == null) { throw new Exception($"Type {typeValue} not have constructor with not parameters"); } il.Newobj(constr); il.Stloc(currentItemValue); BinaryStruct.CompileReader(currentStruct.CurrentStorage.GetTypeInfo(typeValue, currentStruct.Scheme), il, binaryStruct, buffer, offset, currentItemValue, typeSize); } il.Ldloc(list); il.Ldloc(currentItemKey); il.Ldloc(currentItemValue); il.Call(prop.PropertyInfo.PropertyType.GetMethod("Add"), isVirtual: true); //end body il.Ldc_I4(1); il.Ldloc(ivar); il.Add(); il.Stloc(ivar); il.Ldloc(ivar); il.Ldloc(len); il.Clt(false); il.Brtrue(point); il.MarkLabel(exitLabel); }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var exitLabel = il.DefineLabel("exit"); BinaryStruct.ReadObjectNull(il, exitLabel, buffer, offset, typeSize); var len = il.DeclareLocal(typeof(int)); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Stloc(len); BinaryStruct.WriteOffsetAppend(il, offset, 4); if (!listValue) { il.Ldloc(result); il.Ldarg(1); } else { il.Ldloc(binaryStruct); } il.Call(codingMethodInfo); il.Castclass(typeof(UTF8Encoding)); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(len); il.Call(currentStruct.Coding.GetType().GetMethod("GetString", new Type[] { typeof(byte[]), typeof(int), typeof(int) }), isVirtual: true); if (!listValue) { il.Call(prop.Setter); } else { il.Stloc(result); } BinaryStruct.WriteOffsetAppend(il, offset, len); il.MarkLabel(exitLabel); }