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, 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 static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) { EmitBne(il, propertyInfo.GetMethod, r0); } else if (StaticEqualsTypes.ContainsKey(propertyType)) { EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); } else if (InstanceEqualsTypes.ContainsKey(propertyType)) { EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); } else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) { EmitNullableBne(il, propertyInfo.GetMethod, r0); } else if (nullableType != null) { EmitNullableEquals(il, propertyInfo.GetMethod, r0); } else { EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return(method.CreateDelegate(typeof(Func <, ,>).MakeGenericType(type, type, typeof(bool)))); }
public void TestStarg2() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(int), typeof(int) }, typeof(TestArgumentOutOfRange)); var il = new GroboIL(method); il.Ldc_I4(0); il.Starg(0); il.Ldc_I4(0); il.Starg(1); il.Ldc_I4(0); Assert.Throws <ArgumentOutOfRangeException>(() => il.Starg(2)); }
public void BuildSizeCounter(SizeCounterBuilderContext sizeCounterBuilderContext) { var method = new DynamicMethod("Count_" + Type.Name + "_" + Guid.NewGuid(), typeof(int), new[] { Type, typeof(bool), typeof(WriterContext) }, sizeCounterBuilderContext.Module, true); sizeCounterBuilderContext.SetSizeCounterMethod(Type, method); using (var il = new GroboIL(method)) { var context = new SizeCounterMethodBuilderContext(sizeCounterBuilderContext, il); var notEmptyLabel = il.DefineLabel("notEmpty"); if (CheckEmpty(context, notEmptyLabel)) // Check if obj is empty { context.ReturnForNull(); // return for null } il.MarkLabel(notEmptyLabel); // Now we know that obj is not empty if (!Type.IsValueType && IsReference && sizeCounterBuilderContext.GroBufWriter.Options.HasFlag(GroBufOptions.PackReferences)) { // Pack reference var index = il.DeclareLocal(typeof(int)); context.LoadContext(); // stack: [context] il.Dup(); // stack: [context, context] il.Ldfld(WriterContext.IndexField); // stack: [context, context.index] il.Stloc(index); // index = context.index; stack: [context] il.Ldfld(WriterContext.ObjectsField); // stack: [context.objects] context.LoadObj(); // stack: [context.objects, obj] il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.ContainsKey(null))); // stack: [context.object.ContainsKey(obj)] var storeLocationLabel = il.DefineLabel("storeLocation"); il.Brfalse(storeLocationLabel); // if(!context.objects.ContainsKey(obj)) goto storeLocation; stack: [] context.LoadContext(); // stack: [context] il.Dup(); // stack: [context, context] il.Ldfld(WriterContext.ReferencesField); // stack: [context, context.references] il.Ldc_I4(1); // stack: [context, context.references, 1] il.Add(); // stack: [context, context.references + 1] il.Stfld(WriterContext.ReferencesField); // context.references += 1; stack: [] il.Ldc_I4(5); // stack: [5] il.Ret(); // return 5 il.MarkLabel(storeLocationLabel); context.LoadContext(); // stack: [context] il.Ldfld(typeof(WriterContext).GetField("objects", BindingFlags.Public | BindingFlags.Instance)); // stack: [context.objects] context.LoadObj(); // stack: [context.objects, obj] il.Ldloc(index); // stack: [context.objects, obj, index] il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.Add(null, 0))); // context.objects.Add(obj, index); } CountSizeNotEmpty(context); // Count size il.Ret(); } var @delegate = method.CreateDelegate(typeof(SizeCounterDelegate <>).MakeGenericType(Type)); var pointer = GroBufHelpers.ExtractDynamicMethodPointer(method); sizeCounterBuilderContext.SetSizeCounterPointer(Type, pointer, @delegate); }
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 TryGetValueDelegate <T> Build <T>(string[] keys, T[] values) { var trie = BuildTrie(keys); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(T[]), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(2); // stack: [ref value] il.Initobj(typeof(T)); // value = default(value); stack: [] var index = il.DeclareLocal(typeof(int), "index"); il.Ldc_I4(0); // stack: [0] il.Stloc(index); // index = 0; stack: [] var length = il.DeclareLocal(typeof(int), "length"); il.Ldarg(1); // stack: [key] il.Call(stringLengthGetter); // stack: [key.Length] il.Stloc(length); // length = key.Length; stack: [] var context = new EmittingContext { Il = il, Index = index, Length = length, CurChar = il.DeclareLocal(typeof(char)) }; InlineTrie <T>(trie, context); } return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values)); }
public void WithExceptions() { var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(string), true); using (var il = new GroboIL(dynamicMethod, false)) { var endLabel = il.DefineLabel("end"); var resultLocal = il.DeclareLocal(typeof(int), "result"); il.BeginExceptionBlock(); il.Ldarg(0); il.Ldarg(1); il.Div(false); il.Stloc(resultLocal); il.BeginCatchBlock(typeof(DivideByZeroException)); il.Pop(); il.WriteLine("Division by zero caught"); il.Ldc_I4(0); il.Stloc(resultLocal); il.BeginFinallyBlock(); il.WriteLine("It is finally"); il.EndExceptionBlock(); il.MarkLabel(endLabel); il.Ldloc(resultLocal); il.Ret(); } DynamicMethodTracingInstaller.InstallTracing(dynamicMethod); var func = (Func <int, int, int>)dynamicMethod.CreateDelegate(typeof(Func <int, int, int>)); Console.WriteLine(func(12, 5)); Console.WriteLine(func(5, 0)); }
private void LoadValue(BitsValue value) { Generator.Ldc_I8((long)value.Number); Generator.Conv <ulong>(); Generator.Ldc_I4(value.Length); NumberToBitsValue(true); }
private object BuildDelegate <T>(MetadataForModel metadata) { var dynamicMethod = GetDynamicMethod <T>(); using (var il = new GroboIL(dynamicMethod)) { il.Ldarg(0); il.Callnonvirt(GetStartRowMethod()); foreach (var emitInfo in metadata.EmitInfos) { il.Ldarg(0); il.Ldarg(1); il.Callnonvirt(emitInfo.Getter); if (emitInfo.PostgresType != null) { il.Ldc_I4((int)emitInfo.PostgresType.Value); } il.Callnonvirt(emitInfo.WriteMethod); } il.Ret(); } return(dynamicMethod.CreateDelegate(typeof(Action <NpgsqlBinaryImporter, T>))); }
private ITest BuildCall() { var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public); var doNothingMethod = typeBuilder.DefineMethod("DoNothingImpl", MethodAttributes.Public, typeof(void), Type.EmptyTypes); using (var il = new GroboIL(doNothingMethod)) { il.Ldfld(xField); il.Ldc_I4(1); il.Add(); il.Stfld(xField); il.Ret(); } var method = typeBuilder.DefineMethod("DoNothing", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Call(doNothingMethod); il.Ret(); } typeBuilder.DefineMethodOverride(method, typeof(ITest).GetMethod("DoNothing")); typeBuilder.AddInterfaceImplementation(typeof(ITest)); var type = typeBuilder.CreateType(); return((ITest)Activator.CreateInstance(type)); }
private static void EmitMinusMinusX(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Ldc_I4(1); il.Sub(); il.Dup(); il.Stloc(intLocal); }
private static void EmitXPlusPlus(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Dup(); il.Ldc_I4(1); il.Add(); il.Stloc(intLocal); }
public void TestLabelHasBeenMarkedTwice() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true); var il = new GroboIL(method); var label = il.DefineLabel("L"); il.Ldc_I4(0); il.Brfalse(label); il.Ldc_I4(1); il.Pop(); il.MarkLabel(label); il.Ldc_I4(2); il.Pop(); var e = Assert.Throws <InvalidOperationException>(() => il.MarkLabel(label)); Assert.AreEqual("The label 'L_0' has already been marked", e.Message); }
protected override bool EmitInternal(UnaryExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType) { if (node.Type != typeof(bool) && node.Type != typeof(bool?)) { return(ExpressionEmittersCollection.Emit(Expression.OnesComplement(node.Operand, node.Method), context, returnDefaultValueLabel, whatReturn, extend, out resultType)); } GroboIL il = context.Il; if (node.Method != null) { throw new NotSupportedException("Custom operator '" + node.NodeType + "' is not supported"); } var operand = node.Operand; context.EmitLoadArgument(operand, false, out resultType); if (resultType == typeof(bool)) { il.Ldc_I4(1); il.Xor(); } else if (resultType == typeof(bool?)) { using (var value = context.DeclareLocal(typeof(bool?))) { il.Stloc(value); il.Ldloca(value); context.EmitHasValueAccess(typeof(bool?)); var returnLabel = il.DefineLabel("return"); il.Brfalse(returnLabel); il.Ldloca(value); context.EmitValueAccess(typeof(bool?)); il.Ldc_I4(1); il.Xor(); il.Newobj(nullableBoolConstructor); il.Stloc(value); context.MarkLabelAndSurroundWithSP(returnLabel); il.Ldloc(value); } } else { throw new InvalidOperationException("Cannot perform '" + node.NodeType + "' operator on type '" + resultType + "'"); } return(false); }
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(Vector3)); 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.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(8); il.Add(); il.Call(readBitConverterMethodInfo); il.Call(initialConstructor); //if (listValue) // il.Stloc(result); //else // il.Stloc(r); BinaryStruct.WriteOffsetAppend(il, offset, 12); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
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 static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof (bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) EmitBne(il, propertyInfo.GetMethod, r0); else if (StaticEqualsTypes.ContainsKey(propertyType)) EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); else if (InstanceEqualsTypes.ContainsKey(propertyType)) EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) EmitNullableBne(il, propertyInfo.GetMethod, r0); else if (nullableType != null) EmitNullableEquals(il, propertyInfo.GetMethod, r0); else EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return method.CreateDelegate(typeof(Func<,,>).MakeGenericType(type, type, typeof(bool))); }
protected override bool EmitInternal(TypeBinaryExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType) { bool result; GroboIL il = context.Il; if (!node.Expression.Type.IsAssignableFrom(node.TypeOperand)) { il.Ldc_I4(0); result = false; } else if (node.Expression.Type == node.TypeOperand && node.TypeOperand.IsValueType) { il.Ldc_I4(1); result = false; } else { Type operandType; result = ExpressionEmittersCollection.Emit(node.Expression, context, returnDefaultValueLabel, ResultType.Value, extend, out operandType); if (operandType.IsValueType) { using (var temp = context.DeclareLocal(operandType)) { il.Stloc(temp); il.Ldloca(temp); } } var returnFalseLabel = il.DefineLabel("returnFalse"); il.Dup(); il.Brfalse(returnFalseLabel); il.Call(typeof(object).GetMethod("GetType"), operandType); il.Ldtoken(node.TypeOperand); il.Call(typeof(Type).GetMethod("GetTypeFromHandle")); il.Ceq(); var doneLabel = il.DefineLabel("done"); il.Br(doneLabel); context.MarkLabelAndSurroundWithSP(returnFalseLabel); il.Pop(); il.Ldc_I4(0); context.MarkLabelAndSurroundWithSP(doneLabel); } resultType = typeof(bool); return(result); }
private static void MakeShift(Type elementType, GroboIL il) { var typeCode = GroBufTypeCodeMap.GetTypeCode(elementType); switch (typeCode) { case GroBufTypeCode.Int8: case GroBufTypeCode.UInt8: case GroBufTypeCode.Boolean: break; case GroBufTypeCode.Int16: case GroBufTypeCode.UInt16: il.Ldc_I4(1); il.Shl(); break; case GroBufTypeCode.Int32: case GroBufTypeCode.UInt32: il.Ldc_I4(2); il.Shl(); break; case GroBufTypeCode.Int64: case GroBufTypeCode.UInt64: il.Ldc_I4(3); il.Shl(); break; case GroBufTypeCode.Single: il.Ldc_I4(2); il.Shl(); break; case GroBufTypeCode.Double: il.Ldc_I4(3); il.Shl(); break; default: throw new NotSupportedException("Type '" + elementType + "' is not supported"); } }
private static void BuildIlWithNativeCallingConvention(MethodBuilder methodBuilder) { using (var il = new GroboIL(methodBuilder)) { il.Ldc_I4(10); il.Ldarg(0); il.Calli(CallingConvention.StdCall, typeof(int), new[] { typeof(int) }); il.Ret(); } }
public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values, Func <string, int> hashCodeEvaluator) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(Closure <T>), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true); var hashCodes = keys.Select(hashCodeEvaluator).ToArray(); int n = keys.Length; var indexes = new int[n]; for (int i = 0; i < n; ++i) { indexes[i] = i; } Array.Sort(indexes, (lhs, rhs) => hashCodes[lhs].CompareTo(hashCodes[rhs])); using (var il = new GroboIL(method)) { var retFalseLabel = il.DefineLabel("retFalse"); var hashCode = il.DeclareLocal(typeof(int), "hashCode"); il.Ldarg(0); // stack: [closure] il.Ldfld(HackHelpers.GetField <Closure <T> >(x => x.hashCodeEvaluator)); // stack: [closure.hashCodeEvaluator] il.Ldarg(1); // stack: [closure.hashCodeEvaluator, key] il.Call(typeof(Func <string, int>).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)); // stack: [closure.hashCodeEvaluator(key)] il.Stloc(hashCode); // hashCode = closure.hashCodeEvaluator(key); stack: [] var context = new EmittingContext { Il = il, Keys = keys, HashCodes = hashCodes, Indexes = indexes, HashCode = hashCode, RetFalseLabel = retFalseLabel }; DoBinarySearch <T>(context, 0, n - 1); il.MarkLabel(retFalseLabel); il.Ldarg(2); // stack: [ref value] if (typeof(T).IsValueType) { il.Initobj(typeof(T)); // value = default(T); stack: [] } else { il.Ldnull(); // stack: [ref value, null] il.Stind(typeof(T)); // value = null; stack: [] } il.Ldc_I4(0); // stack: [false] il.Ret(); } var closure = new Closure <T> { hashCodeEvaluator = hashCodeEvaluator, values = values }; return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), closure)); }
private static Tuple <Delegate, IntPtr> EmitListResizer <T>() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(List <T>), typeof(int) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); // stack: [list] il.Ldarg(1); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Call(typeof(List <T>).GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)); // list.EnsureCapacity(arrayIndex + 1); stack: [] il.Ldarg(0); // stack: [list] il.Ldarg(1); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Stfld(typeof(List <T>).GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic)); // list.Count = arrayIndex + 1; stack: [] il.Ret(); } return(new Tuple <Delegate, IntPtr>((Action <List <T>, int>)method.CreateDelegate(typeof(Action <List <T>, int>)), DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method))); }
public void TestFarsh() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { var temp = il.DeclareLocal(typeof(int)); il.Ldarg(0); // stack: [x] var label0 = il.DefineLabel("L"); il.Br(label0); // goto L_0; stack: [x] il.Ldstr("zzz"); il.Ldobj(typeof(DateTime)); il.Mul(); il.Initobj(typeof(int)); var label1 = il.DefineLabel("L"); il.MarkLabel(label1); // stack: [x, 2] il.Stloc(temp); // temp = 2; stack: [x] var label2 = il.DefineLabel("L"); il.MarkLabel(label2); // stack: [cur] il.Ldarg(0); // stack: [cur, x] il.Mul(); // stack: [cur * x = cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(1); // stack: [cur, temp, 1] il.Sub(); // stack: [cur, temp - 1] il.Stloc(temp); // temp = temp - 1; stack: [cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(0); // stack: [cur, temp, 0] il.Bgt(label2, false); // if(temp > 0) goto L_2; stack: [cur] var label3 = il.DefineLabel("L"); il.Br(label3); // goto L_3; stack: [cur] il.MarkLabel(label0); // stack: [x] il.Ldc_I4(2); // stack: [x, 2] il.Br(label1); // goto L_1; stack: [x, 2] il.MarkLabel(label3); // stack: [cur] il.Ret(); // return cur; stack: [] Console.Write(il.GetILCode()); } }
private static void BuildConstructor(TypeBuilder typeBuilder, int n, Context context) { var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(int[]), typeof(MethodCallNode[]) }); using (var il = new GroboIL(constructor)) { for (int i = 0; i < n; ++i) { il.Ldarg(0); // stack: [this] il.Ldarg(1); // stack: [this, keys] il.Ldc_I4(i); // stack: [this, keys, i] il.Ldelem(typeof(int)); // stack: [this, keys[i]] il.Stfld(context.keys[i]); // this.key_{i} = keys[i]; stack: [] il.Ldarg(0); // stack: [this] il.Ldarg(2); // stack: [this, values] il.Ldc_I4(i); // stack: [this, values, i] il.Ldelem(typeof(MethodCallNode)); // stack: [this, values[i]] il.Stfld(context.values[i]); // this.value_{i} = values[i]; stack: [] } il.Ret(); } }
private static void BuildCount(TypeBuilder typeBuilder, int n) { var property = typeBuilder.DefineProperty("Count", PropertyAttributes.None, typeof(int), Type.EmptyTypes); var getter = typeBuilder.DefineMethod("get_Count", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(int), Type.EmptyTypes); using (var il = new GroboIL(getter)) { il.Ldc_I4(n); il.Ret(); } property.SetGetMethod(getter); typeBuilder.DefineMethodOverride(getter, typeof(MethodCallNodeEdges).GetProperty(property.Name, BindingFlags.Public | BindingFlags.Instance).GetGetMethod()); }
public void TestLabelHasNotBeenMarked_Switch() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true); var il = new GroboIL(method); var label = il.DefineLabel("L"); il.Ldc_I4(0); il.Switch(label); il.Ret(); var e = Assert.Throws <InvalidOperationException>(il.Dispose); Assert.AreEqual("The label 'L_0' has not been marked", e.Message); }
public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(T[]), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true); using (var il = new GroboIL(method)) { for (int i = 0; i < keys.Length; ++i) { il.Ldarg(1); // stack: [key] il.Ldstr(keys[i]); // stack: [key, keys[i]] var nextKeyLabel = il.DefineLabel("nextKey"); il.Call(stringEqualityOperator); // stack: [key == keys[i]] il.Brfalse(nextKeyLabel); // if(key != keys[i]) goto nextKey; stack: [] il.Ldarg(2); // stack: [ref value] il.Ldarg(0); // stack: [ref value, values] il.Ldc_I4(i); // stack: [ref value, values, i] il.Ldelem(typeof(T)); // stack: [ref value, values[i]] il.Stind(typeof(T)); // value = values[i]; stack: [] il.Ldc_I4(1); // stack: [true] il.Ret(); il.MarkLabel(nextKeyLabel); } il.Ldarg(2); // stack: [ref value] if (typeof(T).IsValueType) { il.Initobj(typeof(T)); // value = default(T); stack: [] } else { il.Ldnull(); // stack: [ref value, null] il.Stind(typeof(T)); // value = null; stack: [] } il.Ldc_I4(0); // stack: [false] il.Ret(); } return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values)); }
private static void BuildChildren(TypeBuilder typeBuilder, int n, Context context) { var property = typeBuilder.DefineProperty("Children", PropertyAttributes.None, typeof(IEnumerable <MethodCallNode>), Type.EmptyTypes); var getter = typeBuilder.DefineMethod("get_Children", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(IEnumerable <MethodCallNode>), Type.EmptyTypes); using (var il = new GroboIL(getter)) { il.Ldc_I4(n); // stack: [n] il.Newarr(typeof(MethodCallNode)); // stack: [new int[n] -> values] for (int i = 0; i < n; ++i) { il.Dup(); // stack: [values, values] il.Ldc_I4(i); // stack: [values, values, i] il.Ldarg(0); // stack: [values, values, i, this] il.Ldfld(context.values[i]); // stack: [values, values, i, this.values_{i}] il.Stelem(typeof(MethodCallNode)); // values[i] = this.values_{i}; stack: [values] } il.Castclass(typeof(IEnumerable <MethodCallNode>)); il.Ret(); } property.SetGetMethod(getter); typeBuilder.DefineMethodOverride(getter, typeof(MethodCallNodeEdges).GetProperty(property.Name, BindingFlags.Public | BindingFlags.Instance).GetGetMethod()); }
private static void EmitDefaultTypeValue(GroboIL il, Type type) { switch (Type.GetTypeCode(type)) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Boolean: case TypeCode.Char: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: il.Ldc_I4(0); return; case TypeCode.Int64: case TypeCode.UInt64: il.Ldc_I8(0); return; case TypeCode.Single: il.Ldc_R4(0f); return; case TypeCode.Double: il.Ldc_R8(0d); return; } if (type.IsPointer || type == typeof(UIntPtr) || type == typeof(IntPtr)) { il.Ldc_IntPtr(IntPtr.Zero); il.Conv <UIntPtr>(); } else if (type.IsEnum) { EmitDefaultTypeValue(il, Enum.GetUnderlyingType(type)); } else if (type.IsValueType) { var local = il.DeclareLocal(type); il.Ldloca(local); il.Initobj(type); il.Ldloc(local); } else { il.Ldnull(); } }
private Tuple <Action, MethodInfo> Build() { var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes, Module, true); using (var il = new GroboIL(dynamicMethod)) { il.Ldfld(xField); il.Ldc_I4(1); il.Add(); il.Stfld(xField); il.Ret(); } return(new Tuple <Action, MethodInfo>((Action)dynamicMethod.CreateDelegate(typeof(Action)), dynamicMethod)); }