private static void SomeMethod(TypeBuilder tb, SilmMI nb, OnlyMI target) { Type[] vs = nb.ParaTypes; ILGenerator g = tb.DefineMethod(nb.Name, mattrb, cc, nb.RetType, vs).GetILGenerator(); int max = nb.ParaLength; for (int x = 0; x < max;) { if (vs[x].IsByRef) { g.Emit_Ldarga(++x); // instance } else { g.Emit_Ldarg(++x); } } g.Emit(OpCodes.Call, target.Info); g.Emit(OpCodes.Ret); }
public bool Equals(SilmMI other) { if (VName != other.VName || RetType != other.RetType || ParaLength != other.ParaLength) { return(false); } int x = ParaLength; Type[] me = ParaTypes; Type[] ot = other.ParaTypes; while (--x >= 0) { if (me[x] != ot[x]) { return(false); } } return(true); }
/// <exception cref="Exception">Thrown when TargetField attribute cannot be found in the property</exception> /// <exception cref="InvalidOperationException">Thrown when try to invalid operation</exception> /// <summary> /// Create an interface implementation for dynamic type <paramref name="t"/> /// </summary> /// <typeparam name="T">Interface type</typeparam> /// <param name="t"> /// Find only public static fields and methods /// Using static types(as opposed to dynamic types) is inefficient /// </param> /// <returns>Is not null if the method succeeds</returns> public static T Make <T>(Type t) where T : class { Type temp = typeof(T); if (!temp.IsInterface || temp.IsNotPublic || t == null || !(t.IsAbstract && t.IsSealed)) { return(null); } if (cached.TryGetValue(t, out object obj)) { return((T)obj); } PropertyInfo[] implPpt = temp.GetProperties(flag_i); SpMI[] impl = Array.ConvertAll(temp.GetMethods(flag_i), CONV_SPI); OnlyMI[] code = Array.ConvertAll(t.GetMethods(flag_s), CONV_OMI); int init_x = impl.Length; int init_p = implPpt.Length; if (init_x == 0 && init_p == 0) { return(null); } CHashSet <int> xdone = init_x == 0 ? null : new CHashSet <int>(init_x); StringBuilder sb = new StringBuilder(t.FullName); sb.Append("__ClassWrapper__"); sb.Append(cached.Count); TypeBuilder tb = mdb.DefineType(sb.ToString(), tattrb, null, new Type[1] { temp }); int clen = code.Length; int z = 0; for (; z < init_x; z++) { SilmMI k = impl[z]; int x = clen; while (--x >= 0) { if (code[x].Equals(k) && xdone.Add(x)) { SomeMethod(tb, k, code[x]); break; } } } if (xdone != null && init_x != xdone.Count) { throw new InvalidOperationException("Some methods could not be implemented", GETMOREINFO(temp, init_x, xdone)); } for (z = 0; z < init_p; z++) { if (implPpt[z].GetCustomAttribute <TargetFieldAttribute>() is TargetFieldAttribute tfa) { PropertyInfo pp = implPpt[z]; temp = pp.PropertyType; if (tfa.refm ^ temp.IsByRef) { throw new InvalidOperationException("Incorrect attribute declare", GETMOREINFO(temp.IsByRef)); } else if (pp.GetSetMethod() != null) { throw new InvalidOperationException("use ref return type instead of set accessor", GETMOREINFO()); } if (t.GetField(pp.GetCustomAttribute <TargetFunctionAttribute>()?.name ?? tfa.name, flag_sa) is FieldInfo fd) { FieldMethod(tb, pp.GetGetMethod(false), fd, tfa.refm); } else { throw new InvalidOperationException($"Field not found: {tfa.name}"); } } else { throw new Exception("Missing attribute"); } } obj = FormatterServices.GetUninitializedObject(tb.CreateType()); cached.Add(t, obj); return((T)obj); }