Skip to content

Commit

Permalink
[generator] Throw PlatformNotSupportException in 32-bit mode for 64-b…
Browse files Browse the repository at this point in the history
…it-only iOS API. Fixes #4689. (#4954)

Throw PlatformNotSupportedException for iOS API that was introduced in iOS 11+
in 32-bit mode, since that API is clearly not available in any 32-bit capable
iOS version.

This makes the 32-bit version of Xamarin.iOS.dll smaller (from 15.282.176
bytes to 14.575.616 bytes, ~700kb smaller - small enough that this makes the
dontlink test work in 32-bit mode again on device).

Fixes #4689.
  • Loading branch information
rolfbjarne authored Oct 11, 2018
1 parent f96faaa commit ffd85c9
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/foundation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13492,10 +13492,9 @@ interface NSUnitTemperature : NSSecureCoding {
NSDimension BaseUnit { get; }
}

#if !WATCH && !TVOS
[Mac (10,8), iOS (11,0), NoWatch, NoTV]
partial interface NSFileManager {

[iOS (11, 0), NoTV, NoWatch]
[Mac (10, 8), Export ("trashItemAtURL:resultingItemURL:error:")]
bool TrashItem (NSUrl url, out NSUrl resultingItemUrl, out NSError error);

Expand All @@ -13515,7 +13514,6 @@ interface NSFileProviderService
[Export ("name")]
string Name { get; }
}
#endif

#if MONOMAC
partial interface NSFilePresenter {
Expand Down
77 changes: 77 additions & 0 deletions src/generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3942,6 +3942,22 @@ AvailabilityBaseAttribute GetIntroduced (MethodInfo mi, PropertyInfo pi)
return mi.GetAvailability (AvailabilityKind.Introduced) ?? pi.GetAvailability (AvailabilityKind.Introduced);
}

bool Is64BitiOSOnly (ICustomAttributeProvider provider)
{
if (BindThirdPartyLibrary)
return false;
if (BindingTouch.CurrentPlatform != PlatformName.iOS)
return false;
var attrib = provider.GetAvailability (AvailabilityKind.Introduced);
if (attrib == null) {
var minfo = provider as MemberInfo;
if (minfo != null && minfo.DeclaringType != null)
return Is64BitiOSOnly (minfo.DeclaringType);
return false;
}
return attrib.Version.Major >= 11;
}

//
// Generates the code necessary to lower the MonoTouch-APIs to something suitable
// to be passed to Objective-C.
Expand Down Expand Up @@ -4754,6 +4770,12 @@ void GenerateProperty (Type type, PropertyInfo pi, List<string> instance_fields_
print ("get; ");
} else {
print ("get {");
var is32BitNotSupported = Is64BitiOSOnly (pi);
if (is32BitNotSupported) {
print ("#if ARCH_32");
print ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
print ("#else");
}
if (debug)
print ("Console.WriteLine (\"In {0}\");", pi.GetGetMethod ());
if (is_model)
Expand All @@ -4778,6 +4800,8 @@ void GenerateProperty (Type type, PropertyInfo pi, List<string> instance_fields_
indent--;
}
}
if (is32BitNotSupported)
print ("#endif");
print ("}\n");
}
}
Expand Down Expand Up @@ -4805,6 +4829,12 @@ void GenerateProperty (Type type, PropertyInfo pi, List<string> instance_fields_
print ("set; ");
} else {
print ("set {");
var is32BitNotSupported = Is64BitiOSOnly (pi);
if (is32BitNotSupported) {
print ("#if ARCH_32");
print ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
print ("#else");
}
if (debug)
print ("Console.WriteLine (\"In {0}\");", pi.GetSetMethod ());

Expand All @@ -4830,6 +4860,8 @@ void GenerateProperty (Type type, PropertyInfo pi, List<string> instance_fields_
}
}
}
if (is32BitNotSupported)
print ("#endif");
print ("}");
}
}
Expand Down Expand Up @@ -5213,6 +5245,13 @@ void GenerateMethod (MemberInformation minfo)
}

print ("{");

var is32BitNotSupported = Is64BitiOSOnly ((ICustomAttributeProvider) minfo.method ?? minfo.property);
if (is32BitNotSupported) {
print ("#if ARCH_32");
print ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
print ("#else");
}
if (debug)
print ("\tConsole.WriteLine (\"In {0}\");", mi);

Expand All @@ -5237,6 +5276,8 @@ void GenerateMethod (MemberInformation minfo)
indent--;
}
}
if (is32BitNotSupported)
print ("#endif");
print ("}\n");
}

Expand Down Expand Up @@ -6177,6 +6218,7 @@ public void Generate (Type type)
var initSelector = (InlineSelectors || BindThirdPartyLibrary) ? "Selector.GetHandle (\"init\")" : "Selector.Init";
var initWithCoderSelector = (InlineSelectors || BindThirdPartyLibrary) ? "Selector.GetHandle (\"initWithCoder:\")" : "Selector.InitWithCoder";
string v = UnifiedAPI && class_mod == "abstract " ? "protected" : ctor_visibility;
var is32BitNotSupported = Is64BitiOSOnly (type);
if (external) {
if (!disable_default_ctor) {
GeneratedCode (sw, 2);
Expand All @@ -6188,12 +6230,19 @@ public void Generate (Type type)
sw.WriteLine ("\t\t[Export (\"init\")]");
sw.WriteLine ("\t\t{0} {1} () : base (NSObjectFlag.Empty)", v, TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (is_direct_binding_value != null)
sw.WriteLine ("\t\t\tIsDirectBinding = {0};", is_direct_binding_value);
if (debug)
sw.WriteLine ("\t\t\tConsole.WriteLine (\"{0}.ctor ()\");", TypeName);
sw.WriteLine ("\t\t\tInitializeHandle (global::{1}.IntPtr_objc_msgSend (this.Handle, global::{2}.{0}), \"init\");", initSelector, ns.Messaging, ns.CoreObjCRuntime);
sw.WriteLine ("\t\t\t");
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
sw.WriteLine ("\t\t}");
}
} else {
Expand All @@ -6207,12 +6256,19 @@ public void Generate (Type type)
sw.WriteLine ("\t\t[Export (\"init\")]");
sw.WriteLine ("\t\t{0} {1} () : base (NSObjectFlag.Empty)", v, TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
var indentation = 3;
WriteIsDirectBindingCondition (sw, ref indentation, is_direct_binding, is_direct_binding_value,
() => string.Format ("InitializeHandle (global::{1}.IntPtr_objc_msgSend (this.Handle, global::{2}.{0}), \"init\");", initSelector, ns.Messaging, ns.CoreObjCRuntime),
() => string.Format ("InitializeHandle (global::{1}.IntPtr_objc_msgSendSuper (this.SuperHandle, global::{2}.{0}), \"init\");", initSelector, ns.Messaging, ns.CoreObjCRuntime));

WriteMarkDirtyIfDerived (sw, type);
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
Expand All @@ -6229,6 +6285,11 @@ public void Generate (Type type)
sw.WriteLine ("\t\t[Export (\"initWithCoder:\")]");
sw.WriteLine ("\t\t{0} {1} (NSCoder coder) : base (NSObjectFlag.Empty)", UnifiedAPI ? v : "public", TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (nscoding) {
if (debug)
sw.WriteLine ("\t\t\tConsole.WriteLine (\"{0}.ctor (NSCoder)\");", TypeName);
Expand All @@ -6241,6 +6302,8 @@ public void Generate (Type type)
} else {
sw.WriteLine ("\t\t\tthrow new InvalidOperationException (\"Type does not conform to NSCoding\");");
}
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
Expand All @@ -6250,18 +6313,32 @@ public void Generate (Type type)
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.WriteLine ("\t\t{0} {1} (NSObjectFlag t) : base (t)", UnifiedAPI ? "protected" : "public", TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\t\t\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (is_direct_binding_value != null)
sw.WriteLine ("\t\t\tIsDirectBinding = {0};", is_direct_binding_value);
WriteMarkDirtyIfDerived (sw, type);
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
GeneratedCode (sw, 2);
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.WriteLine ("\t\t{0} {1} (IntPtr handle) : base (handle)", UnifiedAPI ? "protected internal" : "public", TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\t\t\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (is_direct_binding_value != null)
sw.WriteLine ("\t\t\tIsDirectBinding = {0};", is_direct_binding_value);
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
WriteMarkDirtyIfDerived (sw, type);
sw.WriteLine ("\t\t}");
sw.WriteLine ();
Expand Down

1 comment on commit ffd85c9

@xamarin-release-manager
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build was (probably) aborted

🔥 Jenkins job (on internal Jenkins) failed in stage(s) 'Test run' 🔥 : hudson.AbortException: script returned exit code 2

Build succeeded
API Diff (from stable)
ℹ️ API Diff (from PR only) (please review changes)
ℹ️ Generator Diff (please review changes)
🔥 Test run failed 🔥

Test results

1 tests failed, 0 tests skipped, 224 tests passed.

Failed tests

  • Xtro/Mac: BuildFailure

Please sign in to comment.