protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { using (Compiler.Local oldValue = ctx.GetLocalWithValue(expectedType, valueFrom)) using (Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) using (Compiler.Local field = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) { ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); ctx.StoreValue(token); Compiler.CodeLabel next = ctx.DefineLabel(), processField = ctx.DefineLabel(), end = ctx.DefineLabel(); ctx.MarkLabel(next); ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); ctx.CopyValue(); ctx.StoreValue(field); ctx.LoadValue(Tag); // = 1 - process ctx.BranchIfEqual(processField, true); ctx.LoadValue(field); ctx.LoadValue(1); // < 1 - exit ctx.BranchIfLess(end, false); // default: skip ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); ctx.Branch(next, true); // process ctx.MarkLabel(processField); if (Tail.RequiresOldValue) { if (expectedType.IsValueType) { ctx.LoadAddress(oldValue, expectedType); ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); } else { ctx.LoadValue(oldValue); } } Tail.EmitRead(ctx, null); // note we demanded always returns a value if (expectedType.IsValueType) { ctx.EmitCtor(expectedType, Tail.ExpectedType); // re-nullable<T> it } ctx.StoreValue(oldValue); ctx.Branch(next, false); // outro ctx.MarkLabel(end); ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); ctx.LoadValue(oldValue); // load the old value } }
static InterlockedMethods() { #if !WINRT Type type = JVM.Import(typeof(System.Threading.Interlocked)); AddInt32 = type.GetMethod("Add", new Type[] { Types.Int32.MakeByRefType(), Types.Int32 }); CompareExchangeInt32 = type.GetMethod("CompareExchange", new Type[] { Types.Int32.MakeByRefType(), Types.Int32, Types.Int32 }); CompareExchangeInt64 = type.GetMethod("CompareExchange", new Type[] { Types.Int64.MakeByRefType(), Types.Int64, Types.Int64 }); foreach (MethodInfo m in type.GetMethods()) { if (m.IsGenericMethodDefinition) { switch (m.Name) { case "CompareExchange": CompareExchangeOfT = m; break; case "Exchange": ExchangeOfT = m; break; } } } #else throw new NotImplementedException(); #endif }
bool AddDecimalSupport(Type t) { if (system_decimal != null) { return(true); } var corlib = GetMscorlib(t); system_decimal = new ProcessedType(t) { Assembly = corlib, // this is tracked because the linker (if enabled) needs to be aware of the requirement // but we do not want any code to be generated (it's referenced only from native/glue code) IsNativeReference = true, Methods = new List <ProcessedMethod> (), }; // we don't want to being everything from System.Decimal, but only the bits the support code can call var string_type = corlib.Assembly.GetType("System.String"); var iformatprovider_type = corlib.Assembly.GetType("System.IFormatProvider"); var parse = t.GetMethod("Parse", new Type [] { string_type, iformatprovider_type }); system_decimal.Methods.Add(new ProcessedMethod(parse, this)); var tostring = t.GetMethod("ToString", new Type [] { iformatprovider_type }); system_decimal.Methods.Add(new ProcessedMethod(tostring, this)); AddExtraType(system_decimal); return(true); }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) { if (types == null) types = EmptyTypes; #if PORTABLE MethodInfo method = declaringType.GetMethod(name, types); if (method != null && method.IsStatic) method = null; return method; #else return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); #endif }
public static ParseableSerializer TryCreate(Type type, TypeModel model) { if (type == null) throw new ArgumentNullException("type"); #if WINRT || PORTABLE || COREFX MethodInfo method = null; #if WINRT || COREFX foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse")) #else foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) #endif { ParameterInfo[] p; if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string)) { method = tmp; break; } } #else MethodInfo method = type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly, null, new Type[] { model.MapType(typeof(string)) }, null); #endif if (method != null && method.ReturnType == type) { if (Helpers.IsValueType(type)) { MethodInfo toString = GetCustomToString(type); if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools } return new ParseableSerializer(method); } return null; }
private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type) { switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.Byte: case ProtoTypeCode.Char: case ProtoTypeCode.Double: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.Int64: case ProtoTypeCode.SByte: case ProtoTypeCode.Single: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: case ProtoTypeCode.UInt64: ctx.BranchIfEqual(label, false); break; default: MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static, null, new Type[] { type, type }, null); if (method == null || method.ReturnType != ctx.MapType(typeof(bool))) { throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName); } ctx.EmitCall(method); ctx.BranchIfTrue(label, false); break; } }
private static void EmitConversion(CodeEmitter ilgen, Type converterType, string method) { CodeEmitterLocal converter = ilgen.UnsafeAllocTempLocal(converterType); ilgen.Emit(OpCodes.Ldloca, converter); ilgen.Emit(OpCodes.Call, converterType.GetMethod(method)); }
private static MethodInfo GetCustomToString(Type type) { #if WINRT foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString")) { if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) { return(method); } } return(null); #elif PORTABLE MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes); if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) { return(null); } return(method); #else return(type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Helpers.EmptyTypes, null)); #endif }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { #if PORTABLE throw new InvalidOperationException("Unable to GetMethod with ParameterTypes in PCL version"); #else return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null)); #endif }
public override void Emit(CodeGen g, Operator op) { Type dt = g.TypeMapper.MapType(typeof(Delegate)); g.IL.Emit(OpCodes.Call, (MethodInfo)dt.GetMethod("Remove", BindingFlags.Public | BindingFlags.Static, null, new Type[] { dt, dt }, null)); g.IL.Emit(OpCodes.Castclass, ReturnType); }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) { if (types == null) { types = EmptyTypes; } #if PORTABLE || COREFX MethodInfo method = declaringType.GetMethod(name, types); if (method != null && method.IsStatic) { method = null; } return(method); #else return(declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null)); #endif }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { #if PORTABLE foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name && IsMatch(method.GetParameters(), parameterTypes)) return method; } return null; #else return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); #endif }
protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { // int i and T[] arr using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int)))) { bool writePacked = (options & OPTIONS_WritePacked) != 0; bool fixedLengthPacked = writePacked && CanUsePackedPrefix(); using (Compiler.Local token = (writePacked && !fixedLengthPacked) ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) { Type mappedWriter = ctx.MapType(typeof(ProtoWriter)); if (writePacked) { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.String); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader")); if (fixedLengthPacked) { // write directly - no need for buffering ctx.LoadLength(arr, false); ctx.LoadValue((int)packedWireType); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("WritePackedPrefix")); } else { ctx.LoadValue(arr); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("StartSubItem")); ctx.StoreValue(token); } ctx.LoadValue(fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("SetPackedField")); } EmitWriteArrayLoop(ctx, i, arr); if (writePacked) { if (fixedLengthPacked) { ctx.LoadValue(fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("ClearPackedField")); } else { ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("EndSubItem")); } } } } }
protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { // int i and T[] arr using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int)))) { bool writePacked = (options & OPTIONS_WritePacked) != 0; using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) { Type mappedWriter = ctx.MapType(typeof(ProtoWriter)); if (writePacked) { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.String); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader")); ctx.LoadValue(arr); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("StartSubItem")); ctx.StoreValue(token); ctx.LoadValue(fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("SetPackedField")); } EmitWriteArrayLoop(ctx, i, arr); if (writePacked) { ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(mappedWriter.GetMethod("EndSubItem")); } } } }
static MethodInfo GetMethod(string assembly, string typeName, string method) { foreach (Assembly asm in universe.GetAssemblies()) { if (asm.GetName().Name.Equals(assembly, StringComparison.OrdinalIgnoreCase)) { Type type = asm.GetType(typeName); if (type != null) { return(type.GetMethod(method, BindingFlags.Public | BindingFlags.Static)); } } } return(null); }
bool TryGetImplementedMethod(Type type, string name, Type[] paramTypes, out MethodInfo result) { var dotName = "." + name; foreach (var m in type.GetMethods(_memberFlags)) { if (!m.Name.EndsWith(dotName)) continue; result = type.GetMethod(m.Name, _memberFlags, _binder, paramTypes, null); if (result != null) return true; } return TryGetInterfaceMethod(type, name, paramTypes, out result); }
private static MethodInfo GetCustomToString(Type type) { #if WINRT foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString")) { if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method; } return null; #elif PORTABLE || COREFX MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes); if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null; return method; #else return type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Helpers.EmptyTypes, null); #endif }
private static MethodInfo GetCustomToString(Type type) { // ## 苦竹 屏蔽 ## //#if WINRT // foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString")) // { // if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method; // } // return null; //#elif PORTABLE || COREFX // MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes); // if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null; // return method; //#else return(type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Helpers.EmptyTypes, null)); //#endif }
bool AddDateTimeSupport(Type t) { if (system_datetime != null) { return(true); } var corlib = GetMscorlib(t); system_datetime = new ProcessedType(t) { Assembly = corlib, // this is tracked because the linker (if enabled) needs to be aware of the requirement // but we do not want any code to be generated (it's referenced only from native/glue code) IsNativeReference = true, Methods = new List <ProcessedMethod> (), Properties = new List <ProcessedProperty> (), Constructors = new List <ProcessedConstructor> (), }; var ticks = t.GetProperty("Ticks"); system_datetime.Properties.Add(new ProcessedProperty(ticks, this, system_datetime)); var kind = t.GetProperty("Kind"); system_datetime.Properties.Add(new ProcessedProperty(kind, this, system_datetime)); var dtk = corlib.Assembly.GetType("System.DateTimeKind"); var longT = corlib.Assembly.GetType("System.Int64"); var ctorLongKind = t.GetConstructor(new Type [] { longT, dtk }); system_datetime.Constructors.Add(new ProcessedConstructor(ctorLongKind, this, system_datetime)); var toUniversalTime = t.GetMethod("ToUniversalTime"); system_datetime.Methods.Add(new ProcessedMethod(toUniversalTime, this, system_datetime)); AddExtraType(system_datetime); return(true); }
internal void Emit(ClassLoaderWrapper loader, CodeEmitter ilgen) { if (Type != "static" || Class == null || Name == null || Sig == null) { throw new NotImplementedException(); } Type[] redirParamTypes = loader.ArgTypeListFromSig(Sig); for (int i = 0; i < redirParamTypes.Length; i++) { ilgen.EmitLdarg(i); } // HACK if the class name contains a comma, we assume it is a .NET type if (Class.IndexOf(',') >= 0) { #if NETSTANDARD Class = Class.Replace("mscorlib", Universe.CoreLibName); #endif Type type = StaticCompiler.Universe.GetType(Class, true); MethodInfo mi = type.GetMethod(Name, redirParamTypes); if (mi == null) { throw new InvalidOperationException(); } ilgen.Emit(OpCodes.Call, mi); } else { TypeWrapper tw = loader.LoadClassByDottedName(Class); MethodWrapper mw = tw.GetMethodWrapper(Name, Sig, false); if (mw == null) { throw new InvalidOperationException(); } mw.Link(); mw.EmitCall(ilgen); } // TODO we may need a cast here (or a stack to return type conversion) ilgen.Emit(OpCodes.Ret); }
private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType) { il = Override(type, "GetKeyImpl"); Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true)); if (types.Count <= KnownTypes_ArrayCutoff) { knownTypesCategory = KnownTypes_Array; knownTypesLookupType = MapType(typeof(System.Type[]), true); } else { #if NO_GENERICS knownTypesLookupType = null; #else knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary<System.Type, int>), false); #endif if (knownTypesLookupType == null) { knownTypesLookupType = MapType(typeof(Hashtable), true); knownTypesCategory = KnownTypes_Hashtable; } else { knownTypesCategory = KnownTypes_Dictionary; } } knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); switch (knownTypesCategory) { case KnownTypes_Array: { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); // note that Array.IndexOf is not supported under CF il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod( "IndexOf", new Type[] { MapType(typeof(object)) }), null); if (hasInheritance) { il.DeclareLocal(MapType(typeof(int))); // loc-0 il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc_0); BasicList getKeyLabels = new BasicList(); int lastKey = -1; for (int i = 0; i < methodPairs.Length; i++) { if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break; if (lastKey == methodPairs[i].BaseKey) { // add the last label again getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]); } else { // add a new unique label getKeyLabels.Add(ctx.DefineLabel()); lastKey = methodPairs[i].BaseKey; } } Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count]; getKeyLabels.CopyTo(subtypeLabels, 0); ctx.Switch(subtypeLabels); il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value il.Emit(OpCodes.Ret); lastKey = -1; // now output the different branches per sub-type (not derived type) for (int i = subtypeLabels.Length - 1; i >= 0; i--) { if (lastKey != methodPairs[i].BaseKey) { lastKey = methodPairs[i].BaseKey; // find the actual base-index for this base-key (i.e. the index of // the base-type) int keyIndex = -1; for (int j = subtypeLabels.Length; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } ctx.MarkLabel(subtypeLabels[i]); Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Ret); } } } else { il.Emit(OpCodes.Ret); } } break; case KnownTypes_Dictionary: { LocalBuilder result = il.DeclareLocal(MapType(typeof(int))); Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloca_S, result); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null); il.Emit(OpCodes.Brfalse_S, otherwise); il.Emit(OpCodes.Ldloc_S, result); il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Brfalse_S, otherwise); #if FX11 il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); #else if (ilVersion == Compiler.CompilerContext.ILVersion.Net1) { il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); } else { il.Emit(OpCodes.Unbox_Any, MapType(typeof(int))); } #endif il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
internal void WriteNullCheckedTail(Type type, IProtoSerializer tail, Compiler.Local valueFrom) { if (type.IsValueType) { Type underlyingType = null; #if !FX11 underlyingType = Helpers.GetUnderlyingType(type); #endif if (underlyingType == null) { // not a nullable T; can invoke directly tail.EmitWrite(this, valueFrom); } else { // nullable T; check HasValue using (Compiler.Local valOrNull = GetLocalWithValue(type, valueFrom)) { LoadAddress(valOrNull, type); LoadValue(type.GetProperty("HasValue")); CodeLabel @end = DefineLabel(); BranchIfFalse(@end, false); LoadAddress(valOrNull, type); EmitCall(type.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); tail.EmitWrite(this, null); MarkLabel(@end); } } } else { // ref-type; do a null-check LoadValue(valueFrom); CopyValue(); CodeLabel hasVal = DefineLabel(), @end = DefineLabel(); BranchIfTrue(hasVal, true); DiscardValue(); Branch(@end, false); MarkLabel(hasVal); tail.EmitWrite(this, null); MarkLabel(@end); } }
private void DoIt() { AssemblyName aname = new AssemblyName(); aname.Name = Path.GetFileNameWithoutExtension(outFile); if (culture != null) { aname.CultureInfo = new CultureInfo(culture); } string fileName = Path.GetFileName(outFile); AssemblyBuilder ab; /* * Emit Manifest * */ if (isTemplateFile) { aname = ReadCustomAttributesFromTemplateFile(templateFile, aname); } if (!String.IsNullOrEmpty(title)) { AddCattr(typeof(System.Reflection.AssemblyTitleAttribute), title); } if (!String.IsNullOrEmpty(description)) { AddCattr(typeof(System.Reflection.AssemblyDescriptionAttribute), description); } if (!String.IsNullOrEmpty(company)) { AddCattr(typeof(System.Reflection.AssemblyCompanyAttribute), company); } if (!String.IsNullOrEmpty(product)) { AddCattr(typeof(System.Reflection.AssemblyProductAttribute), product); } if (!String.IsNullOrEmpty(copyright)) { AddCattr(typeof(System.Reflection.AssemblyCopyrightAttribute), copyright); } if (!String.IsNullOrEmpty(trademark)) { AddCattr(typeof(System.Reflection.AssemblyTrademarkAttribute), trademark); } SetKeyPair(aname); if (fileName != outFile) { ab = universe.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName(outFile)); } else { ab = universe.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Save); } foreach (CustomAttributeBuilder cb in cattrs) { ab.SetCustomAttribute(cb); } /* * Emit modules */ foreach (ModuleInfo mod in inputFiles) { if (mod.target != null) { File.Copy(mod.fileName, mod.target, true); mod.fileName = mod.target; } bool isAssembly = false; try { AssemblyName.GetAssemblyName(mod.fileName); isAssembly = true; } catch (Exception) { } if (isAssembly) { ReportWarning(1020, "Ignoring included assembly '" + mod.fileName + "'"); } else { ab.__AddModule(universe.OpenRawModule(mod.fileName)); } } /* * Set entry point */ if (entryPoint != null) { string mainClass = entryPoint.Substring(0, entryPoint.LastIndexOf('.')); string mainMethod = entryPoint.Substring(entryPoint.LastIndexOf('.') + 1); MethodInfo mainMethodInfo = null; try { IKVM.Reflection.Type mainType = ab.GetType(mainClass); if (mainType != null) { mainMethodInfo = mainType.GetMethod(mainMethod); } } catch (Exception ex) { Console.WriteLine(ex); } if (mainMethodInfo != null) { ab.SetEntryPoint(mainMethodInfo); } else { Report(1037, "Unable to find the entry point method '" + entryPoint + "'"); } } /* * Emit resources */ ab.DefineVersionInfoResource(); if (win32IconFile != null) { try { ab.__DefineIconResource(File.ReadAllBytes(win32IconFile)); } catch (Exception ex) { Report(1031, "Error reading icon '" + win32IconFile + "' --" + ex); } } if (win32ResFile != null) { try { ab.DefineUnmanagedResource(win32ResFile); } catch (Exception ex) { Report(1019, "Metadata failure creating assembly -- " + ex); } } ModuleBuilder mainModule = null; foreach (ResourceInfo res in resources) { if (res.name == null) { res.name = Path.GetFileName(res.fileName); } foreach (ResourceInfo res2 in resources) { if ((res != res2) && (res.name == res2.name)) { Report(1046, String.Format("Resource identifier '{0}' has already been used in this assembly", res.name)); } } if (res.isEmbedded) { if (mainModule == null) { mainModule = ab.DefineDynamicModule(fileName, fileName, false); } Stream stream = new MemoryStream(File.ReadAllBytes(res.fileName)); mainModule.DefineManifestResource(res.name, stream, res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public); } else { if (res.target != null) { File.Copy(res.fileName, res.target, true); res.fileName = res.target; } // AddResourceFile must receive a file name and not a path. // Drop directory and give warning if we have a path. var resourceFileName = Path.GetFileName(res.fileName); if (Path.GetDirectoryName(res.fileName) != null || Path.IsPathRooted(res.fileName)) { ReportWarning(99999, String.Format("Path '{0}' in the resource name is not supported. Using just file name '{1}'", res.fileName, resourceFileName)); } ab.AddResourceFile(res.name, resourceFileName, res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public); } } PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly; ImageFileMachine machine; switch (platform) { case Platform.X86: pekind |= PortableExecutableKinds.Required32Bit; machine = ImageFileMachine.I386; break; case Platform.X64: pekind |= PortableExecutableKinds.PE32Plus; machine = ImageFileMachine.AMD64; break; case Platform.IA64: machine = ImageFileMachine.IA64; break; case Platform.AnyCPU32Preferred: pekind |= PortableExecutableKinds.Preferred32Bit; machine = ImageFileMachine.I386; break; case Platform.Arm: machine = ImageFileMachine.ARM; break; case Platform.AnyCPU: default: machine = ImageFileMachine.I386; break; } try { ab.Save(fileName, pekind, machine); } catch (Exception ex) { Report(1019, "Metadata failure creating assembly -- " + ex); } }
private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx) { type.DefineDefaultConstructor(MethodAttributes.Public); il = type.DefineTypeInitializer().GetILGenerator(); switch (knownTypesCategory) { case KnownTypes_Array: { Compiler.CompilerContext.LoadValue(il, types.Count); il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type))); index = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Dup); Compiler.CompilerContext.LoadValue(il, index); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); il.Emit(OpCodes.Stelem_Ref); index++; } il.Emit(OpCodes.Stsfld, knownTypes); il.Emit(OpCodes.Ret); } break; case KnownTypes_Dictionary: { Compiler.CompilerContext.LoadValue(il, types.Count); //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null); } il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Compiler.CompilerContext.LoadValue(il, types.Count); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Box, MapType(typeof(int))); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null); } il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) { if(types == null) types = EmptyTypes; #if PORTABLE MethodInfo method = declaringType.GetMethod(name, types); if (method != null && method.IsStatic) method = null; return method; #else return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); #endif }
internal static MethodInfo GetStaticMethod(Type declaringType, string name) { return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); }
private static void LoadAll() { // Types function = Load(typeof(TotemFunction)); value = Load(typeof(TotemValue)); tstring = Load(typeof(TotemString)); arguments = Load(typeof(TotemArguments)); parameter = Load(typeof(TotemParameter)); @bool = Load(typeof(TotemBool)); map = Load(typeof(TotemMap)); array = Load(typeof(TotemArray)); scope = Load(typeof(TotemFunction.ScopeWrapper)); arr_parameters = Load(typeof(TotemParameter[])); sys_bool = Load(typeof(bool)); // Methods value_val = Load(typeof(TotemValue)).GetProperty("ByTotemValue").GetGetMethod(); function_run = Load(typeof(TotemFunction)).GetMethod("TotemRun", r.BindingFlags.NonPublic | r.BindingFlags.Instance); execute = Load(typeof(TotemValue)).GetMethod("Execute"); function_ctor = Load(typeof(TotemFunction)).GetConstructor(r.BindingFlags.NonPublic | r.BindingFlags.Instance, null, new IKType[] { Load(typeof(TotemScope)), Load(typeof(string)), Load(typeof(TotemParameter[])) }, null); function_local_set = Load(typeof(TotemFunction)).GetMethod("LocalSet", r.BindingFlags.NonPublic | r.BindingFlags.Instance); function_local_get = Load(typeof(TotemFunction)).GetMethod("LocalGet", r.BindingFlags.NonPublic | r.BindingFlags.Instance); function_local_dec = Load(typeof(TotemFunction)).GetMethod("LocalDec", r.BindingFlags.NonPublic | r.BindingFlags.Instance); function_env = Load(typeof(TotemFunction)).GetProperty("Scope", r.BindingFlags.NonPublic | r.BindingFlags.Instance).GetGetMethod(true); arguments_ctor = Load(typeof(TotemArguments)).GetConstructor(IKType.EmptyTypes); arguments_add = Load(typeof(TotemArguments)).GetMethod("Add", r.BindingFlags.Public | r.BindingFlags.Instance | r.BindingFlags.DeclaredOnly); number_ctor_long = Load(typeof(TotemNumber)).GetConstructor(new IKType[] { Load(typeof(long)) }); string_ctor = Load(typeof(TotemString)).GetConstructor(new IKType[] { Load(typeof(string)) }); parameter_ctor = Load(typeof(TotemParameter)).GetConstructor(new IKType[] { Load(typeof(string)), Load(typeof(TotemValue)) }); undefined = Load(typeof(TotemValue)).GetProperty("Undefined").GetGetMethod(); @null = Load(typeof(TotemValue)).GetProperty("Null").GetGetMethod(); value_add = Load(typeof(TotemValue)).GetMethod("op_Addition", r.BindingFlags.Static | r.BindingFlags.Public); value_sub = Load(typeof(TotemValue)).GetMethod("op_Subtraction", r.BindingFlags.Static | r.BindingFlags.Public); value_mul = Load(typeof(TotemValue)).GetMethod("op_Multiply", r.BindingFlags.Static | r.BindingFlags.Public); value_div = Load(typeof(TotemValue)).GetMethod("op_Division", r.BindingFlags.Static | r.BindingFlags.Public); value_eq = Load(typeof(TotemValue)).GetMethod("op_Equality", r.BindingFlags.Static | r.BindingFlags.Public); value_neq = Load(typeof(TotemValue)).GetMethod("op_Inequality", r.BindingFlags.Static | r.BindingFlags.Public); value_lt = Load(typeof(TotemValue)).GetMethod("op_LessThan", r.BindingFlags.Static | r.BindingFlags.Public); value_gt = Load(typeof(TotemValue)).GetMethod("op_GreaterThan", r.BindingFlags.Static | r.BindingFlags.Public); value_lte = Load(typeof(TotemValue)).GetMethod("op_LessThanOrEqual", r.BindingFlags.Static | r.BindingFlags.Public); value_gte = Load(typeof(TotemValue)).GetMethod("op_GreaterThanOrEqual", r.BindingFlags.Static | r.BindingFlags.Public); value_incr = Load(typeof(TotemValue)).GetMethod("op_Increment", r.BindingFlags.Static | r.BindingFlags.Public); value_decr = Load(typeof(TotemValue)).GetMethod("op_Decrement", r.BindingFlags.Static | r.BindingFlags.Public); value_istrue = Load(typeof(TotemValue)).GetMethod("op_Explicit", r.BindingFlags.Static | r.BindingFlags.Public, null, r.CallingConventions.Standard, new IKType[] { Load(typeof(TotemValue)) }, null); value_lookup_get = Load(typeof(TotemValue)).GetProperty("Item", value, new IKType[] { value }).GetGetMethod(); value_lookup_set = Load(typeof(TotemValue)).GetProperty("Item", value, new IKType[] { value }).GetSetMethod(); scope_ctor = Load(typeof(TotemFunction.ScopeWrapper)).GetConstructor(new IKType[] { Load(typeof(TotemFunction)) }); dispose = Load(typeof(IDisposable)).GetMethod("Dispose"); get_prop = Load(typeof(TotemValue)).GetMethod("GetProp"); set_prop = Load(typeof(TotemValue)).GetMethod("SetProp"); bool_ctor = Load(typeof(TotemBool)).GetConstructor(new IKType[] { Load(typeof(bool)) }); map_ctor = map.GetConstructor(IKType.EmptyTypes); map_add = map.GetMethod("AddItem"); array_ctor = array.GetConstructor(IKType.EmptyTypes); array_add = array.GetMethod("AddItem"); }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null)); }
private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx) { type.DefineDefaultConstructor(MethodAttributes.Public); il = type.DefineTypeInitializer().GetILGenerator(); switch (knownTypesCategory) { case KnownTypes_Array: { Compiler.CompilerContext.LoadValue(il, _types.Count); il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type))); index = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Dup); Compiler.CompilerContext.LoadValue(il, index); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); il.Emit(OpCodes.Stelem_Ref); index++; } il.Emit(OpCodes.Stsfld, knownTypes); il.Emit(OpCodes.Ret); } break; case KnownTypes_Dictionary: { Compiler.CompilerContext.LoadValue(il, _types.Count); //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null); } il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Compiler.CompilerContext.LoadValue(il, _types.Count); il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); il.Emit(OpCodes.Stsfld, knownTypes); int typeIndex = 0; foreach (SerializerPair pair in methodPairs) { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldtoken, pair.Type.Type); il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); int keyIndex = typeIndex++, lastKey = pair.BaseKey; if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type { keyIndex = -1; // assume epic fail for (int j = 0; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } } Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Box, MapType(typeof(int))); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null); } il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType) { var genInfo = Override(type, "GetKeyImpl"); il = genInfo.GetILGenerator(); Compiler.CompilerContext ctx = new Compiler.CompilerContext(genInfo, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true)); if (_types.Count <= KnownTypes_ArrayCutoff) { knownTypesCategory = KnownTypes_Array; knownTypesLookupType = MapType(typeof(System.Type[]), true); } else { #if NO_GENERICS knownTypesLookupType = null; #else knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary <System.Type, int>), false); #endif if (knownTypesLookupType == null) { knownTypesLookupType = MapType(typeof(Hashtable), true); knownTypesCategory = KnownTypes_Hashtable; } else { knownTypesCategory = KnownTypes_Dictionary; } } knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); switch (knownTypesCategory) { case KnownTypes_Array: { il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); // note that Array.IndexOf is not supported under CF il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod( "IndexOf", new Type[] { MapType(typeof(object)) }), null); if (hasInheritance) { il.DeclareLocal(MapType(typeof(int))); // loc-0 il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc_0); BasicList getKeyLabels = new BasicList(); int lastKey = -1; for (int i = 0; i < methodPairs.Length; i++) { if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) { break; } if (lastKey == methodPairs[i].BaseKey) { // add the last label again getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]); } else { // add a new unique label getKeyLabels.Add(ctx.DefineLabel()); lastKey = methodPairs[i].BaseKey; } } Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count]; getKeyLabels.CopyTo(subtypeLabels, 0); ctx.Switch(subtypeLabels); il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value il.Emit(OpCodes.Ret); lastKey = -1; // now output the different branches per sub-type (not derived type) for (int i = subtypeLabels.Length - 1; i >= 0; i--) { if (lastKey != methodPairs[i].BaseKey) { lastKey = methodPairs[i].BaseKey; // find the actual base-index for this base-key (i.e. the index of // the base-type) int keyIndex = -1; for (int j = subtypeLabels.Length; j < methodPairs.Length; j++) { if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) { keyIndex = j; break; } } ctx.MarkLabel(subtypeLabels[i]); Compiler.CompilerContext.LoadValue(il, keyIndex); il.Emit(OpCodes.Ret); } } } else { il.Emit(OpCodes.Ret); } } break; case KnownTypes_Dictionary: { LocalBuilder result = il.DeclareLocal(MapType(typeof(int))); Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloca_S, result); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null); il.Emit(OpCodes.Brfalse_S, otherwise); il.Emit(OpCodes.Ldloc_S, result); il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; case KnownTypes_Hashtable: { Label otherwise = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, knownTypes); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Brfalse_S, otherwise); #if FX11 il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); #else if (ilVersion == Compiler.CompilerContext.ILVersion.Net1) { il.Emit(OpCodes.Unbox, MapType(typeof(int))); il.Emit(OpCodes.Ldobj, MapType(typeof(int))); } else { il.Emit(OpCodes.Unbox_Any, MapType(typeof(int))); } #endif il.Emit(OpCodes.Ret); il.MarkLabel(otherwise); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Ret); } break; default: throw new InvalidOperationException(); } }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); }
internal void ReadNullCheckedTail(Type type, IProtoSerializer tail, Compiler.Local valueFrom) { #if !FX11 Type underlyingType; if (type.IsValueType && (underlyingType = Helpers.GetUnderlyingType(type)) != null) { if(tail.RequiresOldValue) { // we expect the input value to be in valueFrom; need to unpack it from T? using (Local loc = GetLocalWithValue(type, valueFrom)) { LoadAddress(loc, type); EmitCall(type.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); } } else { Helpers.DebugAssert(valueFrom == null); // not expecting a valueFrom in this case } tail.EmitRead(this, null); // either unwrapped on the stack or not provided if (tail.ReturnsValue) { // now re-wrap the value EmitCtor(type, underlyingType); } return; } #endif // either a ref-type of a non-nullable struct; treat "as is", even if null // (the type-serializer will handle the null case; it needs to allow null // inputs to perform the correct type of subclass creation) tail.EmitRead(this, valueFrom); }
internal DelegateInnerClassTypeWrapper(string name, Type delegateType) : base(Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, name, null) { #if STATIC_COMPILER || STUB_GENERATOR this.fakeType = FakeTypes.GetDelegateType(delegateType); #elif !FIRST_PASS this.fakeType = typeof([email protected]<>).MakeGenericType(delegateType); #endif MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); TypeWrapper[] argTypeWrappers = new TypeWrapper[parameters.Length]; System.Text.StringBuilder sb = new System.Text.StringBuilder("("); MemberFlags flags = MemberFlags.None; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType.IsByRef) { flags |= MemberFlags.DelegateInvokeWithByRefParameter; parameterType = ArrayTypeWrapper.MakeArrayType(parameterType.GetElementType(), 1); } argTypeWrappers[i] = ClassLoaderWrapper.GetWrapperFromType(parameterType); sb.Append(argTypeWrappers[i].SigName); } TypeWrapper returnType = ClassLoaderWrapper.GetWrapperFromType(invoke.ReturnType); sb.Append(")").Append(returnType.SigName); MethodWrapper invokeMethod = new DynamicOnlyMethodWrapper(this, "Invoke", sb.ToString(), returnType, argTypeWrappers, flags); SetMethods(new MethodWrapper[] { invokeMethod }); SetFields(FieldWrapper.EmptyArray); }
internal void EmitBasicRead(Type helperType, string methodName, Type expectedType) { MethodInfo method = helperType.GetMethod( methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (method == null || method.ReturnType != expectedType || method.GetParameters().Length != 1) throw new ArgumentException("methodName"); LoadReaderWriter(); EmitCall(method); }
internal static MethodInfo GetStaticMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); }
internal void EmitWrite(Type helperType, string methodName, Compiler.Local valueFrom) { if (Helpers.IsNullOrEmpty(methodName)) throw new ArgumentNullException("methodName"); MethodInfo method = helperType.GetMethod( methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (method == null || method.ReturnType != MapType(typeof(void))) throw new ArgumentException("methodName"); LoadValue(valueFrom); LoadReaderWriter(); EmitCall(method); }
internal static string GetDelegateInvokeStubName(Type delegateType) { MethodInfo delegateInvoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = delegateInvoke.GetParameters(); string name = null; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsByRef) { name = (name ?? "<Invoke>") + "_" + i; } } return name ?? "Invoke"; }
protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { Type listType; #if NO_GENERICS listType = typeof(BasicList); #else listType = ctx.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType); #endif Type expected = ExpectedType; using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null) using (Compiler.Local newArr = new Compiler.Local(ctx, expected)) using (Compiler.Local list = new Compiler.Local(ctx, listType)) { ctx.EmitCtor(listType); ctx.StoreValue(list); ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false); // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList using (Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) { Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; if (AppendToCollection) { ctx.LoadLength(oldArr, true); ctx.CopyValue(); ctx.StoreValue(oldLen); ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.Add(); ctx.CreateArray(itemType, null); // length is on the stack ctx.StoreValue(newArr); ctx.LoadValue(oldLen); Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); ctx.BranchIfFalse(nothingToCopy, true); ctx.LoadValue(oldArr); ctx.LoadValue(newArr); ctx.LoadValue(0); // index in target ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args)); ctx.MarkLabel(nothingToCopy); ctx.LoadValue(list); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); } else { ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.CreateArray(itemType, null); ctx.StoreValue(newArr); ctx.LoadAddress(list, listType); ctx.LoadValue(newArr); ctx.LoadValue(0); } copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int) MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); if (copyTo == null) { // fallback: CopyTo(Array, int) copyToArrayInt32Args[1] = ctx.MapType(typeof(Array)); copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); } ctx.EmitCall(copyTo); } ctx.LoadValue(newArr); } }
private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type) { switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.Byte: case ProtoTypeCode.Char: case ProtoTypeCode.Double: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.Int64: case ProtoTypeCode.SByte: case ProtoTypeCode.Single: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: case ProtoTypeCode.UInt64: ctx.BranchIfEqual(label, false); break; default: MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static, null, new Type[] { type, type}, null); if (method == null || method.ReturnType != ctx.MapType(typeof(bool))) { throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName); } ctx.EmitCall(method); ctx.BranchIfTrue(label, false); break; } }
public void OutlineType() { bool first; OutlineAttributes(); o.Write(GetTypeVisibility(t)); if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate)) { if (t.IsSealed) { o.Write(t.IsAbstract ? " static" : " sealed"); } else if (t.IsAbstract) { o.Write(" abstract"); } } o.Write(" "); o.Write(GetTypeKind(t)); o.Write(" "); Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only)); Type parent = t.BaseType; if (t.IsSubclassOf(type_multicast_delegate)) { MethodInfo method; method = t.GetMethod("Invoke"); o.Write(FormatType(method.ReturnType)); o.Write(" "); o.Write(GetTypeName(t)); o.Write(" ("); OutlineParams(method.GetParameters()); o.Write(")"); WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(";"); return; } o.Write(GetTypeName(t)); if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum) { first = true; o.Write(" : "); if (parent != null && parent != type_object && parent != type_value_type) { o.Write(FormatType(parent)); first = false; } foreach (Type intf in interfaces) { if (!first) { o.Write(", "); } first = false; o.Write(FormatType(intf)); } } if (t.IsEnum) { Type underlyingType = t.GetEnumUnderlyingType(); if (underlyingType != type_int) { o.Write(" : {0}", FormatType(underlyingType)); } } WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(" {"); o.Indent++; if (t.IsEnum) { bool is_first = true; foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static)) { if (!is_first) { o.WriteLine(","); } is_first = false; o.Write(fi.Name); } o.WriteLine(); o.Indent--; o.WriteLine("}"); return; } first = true; foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags)) { if (!ShowMember(ci)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ci); OutlineConstructor(ci); o.WriteLine(); } first = true; foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags))) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) != 0) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineMethod(m); o.WriteLine(); } first = true; foreach (MethodInfo m in t.GetMethods(DefaultFlags)) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) == 0) { continue; } if (!(m.Name.StartsWith("op_"))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineOperator(m); o.WriteLine(); } first = true; foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags))) { if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) || (pi.CanWrite && ShowMember(pi.GetSetMethod(true))))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(pi); OutlineProperty(pi); o.WriteLine(); } first = true; foreach (FieldInfo fi in t.GetFields(DefaultFlags)) { if (!ShowMember(fi)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(fi); OutlineField(fi); o.WriteLine(); } first = true; foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags))) { if (!ShowMember(ei.GetAddMethod(true))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ei); OutlineEvent(ei); o.WriteLine(); } first = true; foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags))) { if (!ShowMember(ntype)) { continue; } if (first) { o.WriteLine(); } first = false; #if STATIC new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #else new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #endif } o.Indent--; o.WriteLine("}"); }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); }
private static bool IsDelegate(Type type) { // HACK non-public delegates do not get the special treatment (because they are likely to refer to // non-public types in the arg list and they're not really useful anyway) // NOTE we don't have to check in what assembly the type lives, because this is a DotNetTypeWrapper, // we know that it is a different assembly. if (!type.IsAbstract && type.IsSubclassOf(Types.MulticastDelegate) && type.IsVisible) { MethodInfo invoke = type.GetMethod("Invoke"); if (invoke != null) { foreach (ParameterInfo p in invoke.GetParameters()) { // we don't support delegates with pointer parameters if (IsPointerType(p.ParameterType)) { return false; } } return !IsPointerType(invoke.ReturnType); } } return false; }
protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { using (ctx.StartDebugBlockAuto(this)) { using (Compiler.Local oldValue = ctx.GetLocalWithValueForEmitRead(this, valueFrom)) { Compiler.Local tempLocal = null; Compiler.Local valueForTail; Debug.Assert(Tail.RequiresOldValue || Tail.EmitReadReturnsValue); if (Tail.RequiresOldValue) { if (_expectedType.IsValueType) { tempLocal = ctx.Local(Tail.ExpectedType); ctx.LoadAddress(oldValue, _expectedType); ctx.EmitCall(_expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); ctx.StoreValue(tempLocal); valueForTail = tempLocal; } else { valueForTail = oldValue; } } else { valueForTail = null; } // valueForTail contains: // null: when not required old value // oldValue local: when reference type // tempLocal: when nullable value type Tail.EmitRead(ctx, valueForTail); if (_expectedType.IsValueType) { if (!Tail.EmitReadReturnsValue) { ctx.LoadValue(tempLocal); } // note we demanded always returns a value ctx.EmitCtor(_expectedType, Tail.ExpectedType); // re-nullable<T> it } if (Tail.EmitReadReturnsValue || _expectedType.IsValueType) { ctx.StoreValue(oldValue); } if (EmitReadReturnsValue) { ctx.LoadValue(oldValue); } if (!tempLocal.IsNullRef()) { tempLocal.Dispose(); } } } }