[ObjCRuntime] Add a DynamicRegistrarSupported property, and use it in a few places that require the dynamic registrar.

This commit is contained in:
Rolf Bjarne Kvinge 2018-02-02 18:19:13 +01:00
Родитель 5b040406dd
Коммит 0c89cfd7e9
6 изменённых файлов: 47 добавлений и 2 удалений

Просмотреть файл

@ -375,3 +375,11 @@ This indicates a bug in Xamarin.Mac. Please file a bug at [https://bugzilla.xama
A potential workaround would be to disable the `register-protocols`
optimization, by passing `--optimize:-register-protocols` as an additional mmp
argument in the project's Mac Build options.
### <a name="MM8026"/>MM8026: * is not supported when the dynamic registrar has been linked away.
This usually indicates a bug in Xamarin.Mac, because the dynamic registrar should not be linked away if it's needed. Please file a bug at [https://bugzilla.xamarin.com](https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS).
It's possible to force the linker to keep the dynamic registrar by adding
`--optimize=-remove-dynamic-registrar` to the additional mmp arguments in
the project's Mac Build options.

Просмотреть файл

@ -2384,3 +2384,11 @@ This indicates a bug in Xamarin.iOS. Please file a bug at [https://bugzilla.xama
A potential workaround would be to disable the `register-protocols`
optimization, by passing `--optimize:-register-protocols` as an additional
mtouch argument in the project's iOS Build options.
### <a name="MT8026"/>MT8026: * is not supported when the dynamic registrar has been linked away.
This usually indicates a bug in Xamarin.iOS, because the dynamic registrar should not be linked away if it's needed. Please file a bug at [https://bugzilla.xamarin.com](https://bugzilla.xamarin.com/enter_bug.cgi?product=iOS).
It's possible to force the linker to keep the dynamic registrar by adding
`--optimize=-remove-dynamic-registrar` to the additional mtouch arguments in
the project's iOS Build options.

Просмотреть файл

@ -316,6 +316,9 @@ namespace Foundation {
if (does)
return true;
if (!Runtime.DynamicRegistrationSupported)
return false;
object [] adoptedProtocols = GetType ().GetCustomAttributes (typeof (AdoptsAttribute), true);
foreach (AdoptsAttribute adopts in adoptedProtocols){
if (adopts.ProtocolHandle == protocol)

Просмотреть файл

@ -85,6 +85,9 @@ namespace ObjCRuntime {
void SetupBlock (Delegate trampoline, Delegate userDelegate, bool safe)
{
if (!Runtime.DynamicRegistrationSupported)
throw ErrorHelper.CreateError (8026, "BlockLiteral.SetupBlock is not supported when the dynamic registrar has been linked away.");
// We need to get the signature of the target method, so that we can compute
// the ObjC signature correctly (the generated method that's actually
// invoked by native code does not have enough type information to compute
@ -275,7 +278,11 @@ namespace ObjCRuntime {
// with the proper reference count.
BlockLiteral block = new BlockLiteral ();
if (signature == null) {
block.SetupBlock ((Delegate) handlerDelegate, (Delegate) @delegate);
if (Runtime.DynamicRegistrationSupported) {
block.SetupBlock ((Delegate) handlerDelegate, (Delegate) @delegate);
} else {
throw ErrorHelper.CreateError (8026, $"BlockLiteral.GetBlockForDelegate with a null signature is not supported when the dynamic registrar has been linked away (delegate type: {@delegate.GetType ().FullName}).");
}
} else {
block.SetupBlockImpl ((Delegate) handlerDelegate, (Delegate) @delegate, true, signature);
}

Просмотреть файл

@ -36,6 +36,9 @@ namespace ObjCRuntime {
if (map == null)
return;
if (!Runtime.DynamicRegistrationSupported)
return; // Only the dynamic registrar needs the list of registered assemblies.
for (int i = 0; i < map->assembly_count; i++) {
var ptr = Marshal.ReadIntPtr (map->assembly, i * IntPtr.Size);
Runtime.Registrar.SetAssemblyRegistered (Marshal.PtrToStringAuto (ptr));
@ -116,6 +119,8 @@ namespace ObjCRuntime {
}
if (@class == IntPtr.Zero) {
if (!Runtime.DynamicRegistrationSupported)
throw ErrorHelper.CreateError (8026, $"Can't register the class {type.FullName} when the dynamic registrar has been linked away.");
@class = Register (type);
lock (type_to_class)
type_to_class [type] = @class;

Просмотреть файл

@ -162,6 +162,14 @@ namespace ObjCRuntime {
internal static unsafe InitializationOptions* options;
[BindingImpl (BindingImplOptions.Optimizable)]
public static bool DynamicRegistrationSupported {
get {
// The linker may turn calls to this property into a constant
return true;
}
}
internal static bool Initialized {
get { return initialized; }
}
@ -234,7 +242,8 @@ namespace ObjCRuntime {
NSObjectClass = NSObject.Initialize ();
Registrar = new DynamicRegistrar ();
if (DynamicRegistrationSupported)
Registrar = new DynamicRegistrar ();
RegisterDelegates (options);
Class.Initialize (options);
InitializePlatform (options);
@ -538,6 +547,8 @@ namespace ObjCRuntime {
if (a == null)
throw new ArgumentNullException ("a");
if (!DynamicRegistrationSupported)
throw ErrorHelper.CreateError (8026, "Runtime.RegisterAssembly is not supported when the dynamic registrar has been linked away.");
#if MONOMAC
var attributes = a.GetCustomAttributes (typeof (RequiredFrameworkAttribute), false);
@ -1410,6 +1421,9 @@ namespace ObjCRuntime {
if (export == null)
throw new ArgumentNullException ("export");
if (!DynamicRegistrationSupported)
throw ErrorHelper.CreateError (8026, "Runtime.ConnectMethod is not supported when the dynamic registrar has been linked away.");
Registrar.RegisterMethod (type, method, export);
}