Add runtime variable to specify the exception marshalling modes, and mmp/mtouch options to select it.

This commit is contained in:
Rolf Bjarne Kvinge 2016-05-11 12:47:26 +02:00
Родитель b8abf3db01
Коммит 9b4f7532ab
15 изменённых файлов: 164 добавлений и 0 удалений

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

@ -79,6 +79,8 @@ bool xamarin_is_gc_coop = true;
#else
bool xamarin_is_gc_coop = false;
#endif
enum MarshalObjectiveCExceptionMode xamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionModeDefault;
enum MarshalManagedExceptionMode xamarin_marshal_managed_exception_mode = MarshalManagedExceptionModeDefault;
/* Callbacks */

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

@ -19,6 +19,24 @@
extern "C" {
#endif
/* This enum must always match the identical enum in src/ObjCRuntime/ExceptionMode.cs */
enum MarshalObjectiveCExceptionMode : int {
MarshalObjectiveCExceptionModeDefault = 0,
MarshalObjectiveCExceptionModeUnwindManagedCode = 1,
MarshalObjectiveCExceptionModeThrowManagedException = 2,
MarshalObjectiveCExceptionModeAbort = 3,
MarshalObjectiveCExceptionModeDisable = 4,
};
/* This enum must always match the identical enum in src/ObjCRuntime/ExceptionMode.cs */
enum MarshalManagedExceptionMode : int {
MarshalManagedExceptionModeDefault = 0,
MarshalManagedExceptionModeUnwindNativeCode = 1,
MarshalManagedExceptionModeThrowObjectiveCException = 2,
MarshalManagedExceptionModeAbort = 3,
MarshalManagedExceptionModeDisable = 4,
};
extern bool mono_use_llvm; // this is defined inside mono
extern bool xamarin_use_new_assemblies;
@ -32,6 +50,8 @@ extern int xamarin_log_level;
extern const char *xamarin_executable_name;
extern const char *xamarin_arch_name;
extern bool xamarin_is_gc_coop;
extern enum MarshalObjectiveCExceptionMode xamarin_marshal_objectivec_exception_mode;
extern enum MarshalManagedExceptionMode xamarin_marshal_managed_exception_mode;
#ifdef MONOTOUCH
extern NSString* xamarin_crashlytics_api_key;

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

@ -0,0 +1,30 @@
//
// ExceptionMode.cs:
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2016 Xamarin Inc.
using System;
using XamCore.Foundation;
namespace XamCore.ObjCRuntime {
/* This enum must always match the identical enum in runtime/xamarin/main.h */
public enum MarshalObjectiveCExceptionMode {
Default = 0,
UnwindManagedCode = 1, // not available for watchOS/COOP, default for the other platforms
ThrowManagedException = 2, // default for watchOS/COOP
Abort = 3,
Disable = 4, // this will also prevent the corresponding event from working
}
/* This enum must always match the identical enum in runtime/xamarin/main.h */
public enum MarshalManagedExceptionMode {
Default = 0,
UnwindNativeCode = 1, // not available for watchOS/COOP, default for the other platforms
ThrowObjectiveCException = 2, // default for watchOS/COOP
Abort = 3,
Disable = 4, // this will also prevent the corresponding event from working
}
}

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

@ -1393,6 +1393,7 @@ SHARED_SOURCES = \
ObjCRuntime/Dlfcn.cs \
ObjCRuntime/DynamicRegistrar.cs \
ObjCRuntime/ErrorHelper.cs \
ObjCRuntime/ExceptionMode.cs \
ObjCRuntime/IDynamicRegistrar.cs \
ObjCRuntime/Method.cs \
ObjCRuntime/MethodDescription.cs \

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

@ -9,6 +9,8 @@ using Mono.Cecil.Mdb;
using Xamarin.Utils;
using XamCore.ObjCRuntime;
namespace Xamarin.Bundler {
[Flags]
@ -44,6 +46,8 @@ namespace Xamarin.Bundler {
public Mono.Linker.I18nAssemblies I18n;
public bool? EnableCoopGC;
public MarshalObjectiveCExceptionMode MarshalObjectiveCExceptions;
public MarshalManagedExceptionMode MarshalManagedExceptions;
public string PlatformName {
get {
@ -338,6 +342,41 @@ namespace Xamarin.Bundler {
if (!EnableCoopGC.HasValue)
EnableCoopGC = Platform == ApplePlatform.WatchOS;
if (EnableCoopGC.Value) {
switch (MarshalObjectiveCExceptions) {
case MarshalObjectiveCExceptionMode.UnwindManagedCode:
case MarshalObjectiveCExceptionMode.Disable:
throw ErrorHelper.CreateError (89, "The option '{0}' cannot take the value '{1}' when the Coop GC is enabled.", "--marshal-objectivec-exceptions", MarshalObjectiveCExceptions.ToString ().ToLowerInvariant ());
}
switch (MarshalManagedExceptions) {
case MarshalManagedExceptionMode.UnwindNativeCode:
case MarshalManagedExceptionMode.Disable:
throw ErrorHelper.CreateError (89, "The option '{0}' cannot take the value '{1}' when the Coop GC is enabled.", "--marshal-managed-exceptions", MarshalManagedExceptions.ToString ().ToLowerInvariant ());
}
}
bool isSimulatorOrDesktopDebug = EnableDebug;
#if MTOUCH
isSimulatorOrDesktopDebug &= IsSimulatorBuild;
#endif
if (MarshalObjectiveCExceptions == MarshalObjectiveCExceptionMode.Default) {
if (EnableCoopGC.Value) {
MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException;
} else {
MarshalObjectiveCExceptions = isSimulatorOrDesktopDebug ? MarshalObjectiveCExceptionMode.UnwindManagedCode : MarshalObjectiveCExceptionMode.Disable;
}
}
if (MarshalManagedExceptions == MarshalManagedExceptionMode.Default) {
if (EnableCoopGC.Value) {
MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException;
} else {
MarshalManagedExceptions = isSimulatorOrDesktopDebug ? MarshalManagedExceptionMode.UnwindNativeCode : MarshalManagedExceptionMode.Disable;
}
}
}
}
}

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

@ -14,12 +14,59 @@ using System.Runtime.InteropServices;
using System.Text;
using Xamarin.Utils;
using XamCore.ObjCRuntime;
namespace Xamarin.Bundler {
public partial class Driver {
static void AddSharedOptions (Mono.Options.OptionSet options)
{
options.Add ("coop:", "If the Coop GC should be used.", v => { App.EnableCoopGC = ParseBool (v, "coop"); }, hidden: true);
options.Add ("marshal-objectivec-exceptions:", v => {
switch (v) {
case "default":
App.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Default;
break;
case "unwindmanaged":
case "unwindmanagedcode":
App.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.UnwindManagedCode;
break;
case "throwmanaged":
case "throwmanagedexception":
App.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException;
break;
case "abort":
App.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Abort;
break;
case "disable":
App.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Disable;
break;
default:
throw ErrorHelper.CreateError (26, "Could not parse the command line argument '{0}': {1}", "--marshal-objective-exceptions", "Invalid value: " + v);
}
});
options.Add ("marshal-managed-exceptions:", v => {
switch (v) {
case "default":
App.MarshalManagedExceptions = MarshalManagedExceptionMode.Default;
break;
case "unwindnative":
case "unwindnativecode":
App.MarshalManagedExceptions = MarshalManagedExceptionMode.UnwindNativeCode;
break;
case "throwobjectivec":
case "throwobjectivecexception":
App.MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException;
break;
case "abort":
App.MarshalManagedExceptions = MarshalManagedExceptionMode.Abort;
break;
case "disable":
App.MarshalManagedExceptions = MarshalManagedExceptionMode.Disable;
break;
default:
throw ErrorHelper.CreateError (26, "Could not parse the command line argument '{0}': {1}", "--marshal-managed-exceptions", "Invalid value: " + v);
}
});
}
#if MONOMAC

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

@ -97,6 +97,7 @@ mmp_sources = \
$(TOP)/tools/common/cache.cs \
driver.cs \
$(TOP)/src/ObjCRuntime/ErrorHelper.cs \
$(TOP)/src/ObjCRuntime/ExceptionMode.cs \
error.cs \
resolver.cs \
$(MONO_PATH)/mcs/class/Mono.Options/Mono.Options/Options.cs \

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

@ -48,6 +48,7 @@ using Mono.Tuner;
using MonoMac.Tuner;
using Xamarin.Utils;
using Xamarin.Linker;
using XamCore.ObjCRuntime;
namespace Xamarin.Bundler {
public enum RegistrarMode {
@ -877,6 +878,8 @@ namespace Xamarin.Bundler {
sw.WriteLine ("\txamarin_custom_bundle_name = @\"" + custom_bundle_name + "\";");
}
sw.WriteLine ("\txamarin_use_il_registrar = {0};", registrar == RegistrarMode.IL ? "true" : "false");
sw.WriteLine ("\txamarin_marshal_managed_exception_mode = MarshalManagedExceptionMode{0};", App.MarshalManagedExceptions);
sw.WriteLine ("\txamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionMode{0};", App.MarshalObjectiveCExceptions);
sw.WriteLine ();
if (Driver.registrar == RegistrarMode.Static)
sw.WriteLine ("\txamarin_create_classes ();");

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

@ -34,6 +34,7 @@ namespace Xamarin.Bundler {
// MM0079 Internal Error - No executable was copied into the app bundle. Please contact 'support@xamarin.com'
// Warning MT0080 Disabling NewRefCount, --new-refcount:false, is deprecated.
// MM0088 ** Reserved mtouch **
// MM0089 ** Reserved mtouch **
// MM1xxx file copy / symlinks (project related)
// MM14xx Product assemblies
// MM1401 The required '{0}' assembly is missing from the references

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

@ -263,6 +263,9 @@
<Compile Include="..\..\src\ObjCRuntime\ErrorHelper.cs">
<Link>external\ErrorHelper.cs</Link>
</Compile>
<Compile Include="..\..\src\ObjCRuntime\ExceptionMode.cs">
<Link>external\ExceptionMode.cs</Link>
</Compile>
<Compile Include="..\..\src\ObjCRuntime\Registrar.cs">
<Link>external\Registrar.cs</Link>
</Compile>

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

@ -91,6 +91,7 @@ COMMON_SOURCES = \
$(TOP)/src/build/ios/Constants.cs \
error.cs \
$(TOP)/src/ObjCRuntime/ErrorHelper.cs \
$(TOP)/src/ObjCRuntime/ExceptionMode.cs \
$(MONO_DIR)/mcs/class/Mono.Options/Mono.Options/Options.cs
MTOUCH_SOURCES = \

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

@ -96,6 +96,7 @@ namespace Xamarin.Bundler {
// MT0086 A target framework (--target-framework) must be specified when building for TVOS or WatchOS.
// Warning MT0087 <unused>
// MT0088 Cannot disable the Coop GC for watchOS apps. Please remove the --coop:false argument to mtouch.
// MT0089 The option '{0}' cannot take the value '{1}' when the Coop GC is enabled.
// MT0091 This version of Xamarin.iOS requires the {0} {1} SDK (shipped with Xcode {2}) when the managed linker is disabled. Either upgrade Xcode, or enable the managed linker.
// MT0092 <used by Xamarin.Launcher> The option '{0}' is required.
// MT0093 Could not find 'mlaunch'.

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

@ -63,6 +63,7 @@ using Mono.Tuner;
using MonoTouch.Tuner;
using XamCore.Registrar;
using XamCore.ObjCRuntime;
using Xamarin.Linker;
using Xamarin.Utils;
@ -651,6 +652,8 @@ namespace Xamarin.Bundler
sw.WriteLine ("\tmono_use_llvm = {0};", enable_llvm ? "TRUE" : "FALSE");
sw.WriteLine ("\txamarin_log_level = {0};", verbose);
sw.WriteLine ("\txamarin_arch_name = \"{0}\";", abi.AsArchString ());
sw.WriteLine ("\txamarin_marshal_managed_exception_mode = MarshalManagedExceptionMode{0};", app.MarshalManagedExceptions);
sw.WriteLine ("\txamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionMode{0};", app.MarshalObjectiveCExceptions);
if (app.EnableDebug)
sw.WriteLine ("\txamarin_debug_mode = TRUE;");
if (!string.IsNullOrEmpty (app.MonoGCParams))
@ -907,6 +910,9 @@ namespace Xamarin.Bundler
if (app.Registrar == RegistrarMode.Static || app.Registrar == RegistrarMode.LegacyStatic || app.Registrar == RegistrarMode.LegacyDynamic)
return false;
if (app.MarshalObjectiveCExceptions != MarshalObjectiveCExceptionMode.Default || app.Platform == ApplePlatform.WatchOS)
return false;
return true;
}

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

@ -317,6 +317,9 @@
<Compile Include="..\..\src\ObjCRuntime\ErrorHelper.cs">
<Link>external\ErrorHelper.cs</Link>
</Compile>
<Compile Include="..\..\src\ObjCRuntime\ExceptionMode.cs">
<Link>external\ExceptionMode.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Reference Include="System.Core" />

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

@ -21,6 +21,12 @@ void xamarin_setup_impl ()
xamarin_create_classes_Xamarin_iOS ();
#else
xamarin_use_new_assemblies = FALSE;
#endif
xamarin_marshal_managed_exception_mode = MarshalManagedExceptionModeDisable;
#if DEBUG
xamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionModeUnwindManagedCode;
#else
xamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionModeDisabled;
#endif
}