public void RegisterMethod (Type type, MethodInfo minfo, ExportAttribute ea) { RegisterMethod (minfo, ea, type, Class.GetHandle (type), true); }
public void RegisterMethod (MethodInfo minfo, ExportAttribute ea, Type type, IntPtr handle, bool update_map) { IntPtr reg_handle = IntPtr.Zero; IntPtr tramp = IntPtr.Zero; IntPtr sel = Selector.GetHandle (ea.Selector ?? minfo.Name); string signature = Method.Signature (minfo); Type return_type = minfo.ReturnType; reg_handle = minfo.IsStatic ? Class.object_getClass (handle) : handle; if (return_type.IsValueType && !return_type.IsEnum && return_type.Assembly != typeof (object).Assembly && (Runtime.Arch == Arch.DEVICE || Marshal.SizeOf (return_type) > 8)) { if (Runtime.Arch == Arch.SIMULATOR) { if (TypeContainsDouble (return_type)) tramp = minfo.IsStatic ? Method.X86_DoubleABI_StaticStretTrampoline : Method.X86_DoubleABI_StretTrampoline; else tramp = minfo.IsStatic ? Method.StaticStretTrampoline : Method.StretTrampoline; } else { tramp = minfo.IsStatic ? Method.StaticStretTrampoline : Method.StretTrampoline; } } else if (return_type.IsValueType && !return_type.IsEnum && return_type.Assembly != typeof (object).Assembly && Runtime.Arch == Arch.SIMULATOR && Marshal.SizeOf (return_type) > 4) { // for instance CGSize... tramp = minfo.IsStatic ? Method.StaticLongTrampoline : Method.LongTrampoline; } else { switch (signature [0]) { case 'Q': case 'q': tramp = minfo.IsStatic ? Method.StaticLongTrampoline : Method.LongTrampoline; break; case 'f': tramp = minfo.IsStatic ? Method.StaticSingleTrampoline : Method.SingleTrampoline; break; case 'd': tramp = minfo.IsStatic ? Method.StaticDoubleTrampoline : Method.DoubleTrampoline; break; default: tramp = minfo.IsStatic ? Method.StaticTrampoline : Method.Trampoline; break; } } #if DEBUG_REGISTER Console.WriteLine ("[METHOD] Registering {0}[0x{1:x}|{2}] on {3} -> ({4}) tramp: 0x{5}", ea.Selector, (int) sel, Method.Signature (minfo), type, minfo, tramp.ToString ("x")); #endif Class.class_addMethod (reg_handle, sel, tramp, Method.Signature (minfo)); if (update_map) { Dictionary<IntPtr, MethodDescription> methods; lock (lock_obj) { if (!method_map.TryGetValue (type, out methods)) { methods = new Dictionary<IntPtr, MethodDescription> (Runtime.IntPtrEqualityComparer); method_map.Add (type, methods); } methods[sel] = new MethodDescription (minfo, ea.ArgumentSemantic); } } }
public bool SetExportAttribute (ExportAttribute ea, ref List<Exception> exceptions) { if (string.IsNullOrEmpty (ea.Selector)) { AddException (ref exceptions, Registrar.CreateException (4135, this, "The member '{0}' has an Export attribute without a selector. A selector is required.", FullName)); return false; } Selector = ea.Selector; ArgumentSemantic = ea.ArgumentSemantic; IsVariadic = ea.IsVariadic; return true; }