Merge remote-tracking branch 'origin/main' into bump-main-in-xcode14-2022-09-09

This commit is contained in:
Rolf Bjarne Kvinge 2022-09-09 16:54:19 +02:00
Родитель 7717d9b42a ea855fda92
Коммит 9bca30dce6
43 изменённых файлов: 674 добавлений и 129 удалений

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

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Exe</OutputType>
<AssemblyName>Build</AssemblyName>
<NoWarn>$(NoWarn);NU1603</NoWarn> <!-- Xamarin.Messaging.Build.Common 1.6.24 depends on Merq (>= 1.1.0) but Merq 1.1.0 was not found. An approximate best match of Merq 1.1.4 was resolved. -->

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

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../product.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

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

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../product.snk</AssemblyOriginatorKeyFile>

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

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>

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

@ -2685,6 +2685,9 @@ Copyright (C) 2018 Microsoft. All rights reserved.
<_AppContainerDir Condition="'$(IsAppDistribution)' == 'true'">$(ArchivePath)\Products\Applications\</_AppContainerDir>
<AppBundleDir>$(_AppContainerDir)$(_AppBundleName)$(AppBundleExtension)</AppBundleDir>
</PropertyGroup>
<PropertyGroup Condition="'$(_AppContainerDir)' == ''">
<_AppContainerDir>$([System.IO.Path]::GetDirectoryName($(AppBundleDir)))/</_AppContainerDir>
</PropertyGroup>
<PropertyGroup>
<!-- Ensure _AppBundlePath is a relative path (relative to the project directory) and contains a trailing slash -->
<_AppBundlePath>$(AppBundleDir)</_AppBundlePath>

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

@ -312,8 +312,8 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved.
Outputs="$(_LinkSemaphore)">
<PropertyGroup>
<!-- We need to use net5.0 because when building from VS it sets MSBuildRuntimeType to Core and will pick net472 (which doesn't contain the illink assembly) -->
<_RemoteILLinkPath>$(ILLinkTasksAssembly.Replace('$(NetCoreRoot)', '$(_DotNetRootRemoteDirectory)').Replace('net472', 'net6.0').Replace('$([System.IO.Path]::GetFileName('$(ILLinkTasksAssembly)'))', 'illink.dll'))</_RemoteILLinkPath>
<!-- We need to use netX.Y because when building from VS it sets MSBuildRuntimeType to Core and will pick net472 (which doesn't contain the illink assembly) -->
<_RemoteILLinkPath>$(ILLinkTasksAssembly.Replace('$(NetCoreRoot)', '$(_DotNetRootRemoteDirectory)').Replace('net472', 'net$(BundledNETCoreAppTargetFrameworkVersion)').Replace('$([System.IO.Path]::GetFileName('$(ILLinkTasksAssembly)'))', 'illink.dll'))</_RemoteILLinkPath>
</PropertyGroup>
<!-- Include Debug symbols as input so those are copied to the server -->

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

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<MergeSystemAssemblies>false</MergeSystemAssemblies>
<IncludeMSBuildAssets Condition="'$(IncludeMSBuildAssets)' == ''">compile</IncludeMSBuildAssets>

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

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<IncludeMSBuildAssets Condition="'$(IncludeMSBuildAssets)' == ''">compile</IncludeMSBuildAssets>
<SignAssembly>true</SignAssembly>

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

@ -56,8 +56,8 @@ typedef struct {
} MTProperty;
// This structure completely describes everything required to resolve a metadata token
typedef struct MTFullTokenReference {
const char *assembly_name; /* the name of the assembly */
typedef struct __attribute__((packed)) {
uint32_t assembly_index; /* index into the 'assemblies' array in the registration map */
uint32_t module_token;
uint32_t token;
} MTFullTokenReference;
@ -99,10 +99,15 @@ typedef struct __attribute__((packed)) {
const __unsafe_unretained Protocol * const * protocols; // the corresponding native protocols
} MTProtocolMap;
typedef struct __attribute__((packed)) {
const char *name;
const char *mvid;
} MTAssembly;
struct MTRegistrationMap;
struct MTRegistrationMap {
const char **assembly;
const MTAssembly *assemblies;
MTClassMap *map;
const MTFullTokenReference *full_token_references;
// There are some managed types that are not registered because their ObjC

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

@ -59,7 +59,11 @@ namespace CoreFoundation {
// CFRunLoop.h
[StructLayout (LayoutKind.Sequential)]
#if NET
internal unsafe struct CFRunLoopSourceContext {
#else
internal struct CFRunLoopSourceContext {
#endif
public CFIndex Version;
public IntPtr Info;
public IntPtr Retain;
@ -67,9 +71,15 @@ namespace CoreFoundation {
public IntPtr CopyDescription;
public IntPtr Equal;
public IntPtr Hash;
#if NET
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Schedule;
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Cancel;
public delegate* unmanaged<IntPtr, void> Perform;
#else
public IntPtr Schedule;
public IntPtr Cancel;
public IntPtr Perform;
#endif
}
#if NET
@ -145,9 +155,11 @@ namespace CoreFoundation {
[DllImport (Constants.CoreFoundationLibrary)]
extern static /* CFRunLoopSourceRef */ IntPtr CFRunLoopSourceCreate (/* CFAllocatorRef */ IntPtr allocator, /* CFIndex */ nint order, /* CFRunLoopSourceContext* */ ref CFRunLoopSourceContext context);
#if !NET
static ScheduleCallback ScheduleDelegate = (ScheduleCallback) Schedule;
static CancelCallback CancelDelegate = (CancelCallback) Cancel;
static PerformCallback PerformDelegate = (PerformCallback) Perform;
#endif
protected CFRunLoopSourceCustom ()
: base (IntPtr.Zero, true)
@ -155,9 +167,17 @@ namespace CoreFoundation {
gch = GCHandle.Alloc (this);
var ctx = new CFRunLoopSourceContext ();
ctx.Info = GCHandle.ToIntPtr (gch);
#if NET
unsafe {
ctx.Schedule = &Schedule;
ctx.Cancel = &Cancel;
ctx.Perform = &Perform;
}
#else
ctx.Schedule = Marshal.GetFunctionPointerForDelegate (ScheduleDelegate);
ctx.Cancel = Marshal.GetFunctionPointerForDelegate (CancelDelegate);
ctx.Perform = Marshal.GetFunctionPointerForDelegate (PerformDelegate);
#endif
var handle = CFRunLoopSourceCreate (IntPtr.Zero, 0, ref ctx);
InitializeHandle (handle);
@ -165,7 +185,11 @@ namespace CoreFoundation {
delegate void ScheduleCallback (IntPtr info, IntPtr runLoop, IntPtr mode);
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(ScheduleCallback))]
#endif
static void Schedule (IntPtr info, IntPtr runLoop, IntPtr mode)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
@ -182,7 +206,11 @@ namespace CoreFoundation {
delegate void CancelCallback (IntPtr info, IntPtr runLoop, IntPtr mode);
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(CancelCallback))]
#endif
static void Cancel (IntPtr info, IntPtr runLoop, IntPtr mode)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
@ -199,7 +227,11 @@ namespace CoreFoundation {
delegate void PerformCallback (IntPtr info);
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(PerformCallback))]
#endif
static void Perform (IntPtr info)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;

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

@ -330,27 +330,50 @@ namespace CoreVideo {
public delegate CVReturn DisplayLinkOutputCallback (CVDisplayLink displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut);
delegate CVReturn CVDisplayLinkOutputCallback (IntPtr displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut, IntPtr displayLinkContext);
#if NET
[UnmanagedCallersOnly]
static unsafe CVReturn OutputCallback (IntPtr displayLink, CVTimeStamp* inNow, CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, IntPtr displayLinkContext)
#else
static CVDisplayLinkOutputCallback static_OutputCallback = new CVDisplayLinkOutputCallback (OutputCallback);
#if !MONOMAC
[MonoPInvokeCallback (typeof (CVDisplayLinkOutputCallback))]
#endif
static CVReturn OutputCallback (IntPtr displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut, IntPtr displayLinkContext)
#endif
{
GCHandle callbackHandle = GCHandle.FromIntPtr (displayLinkContext);
DisplayLinkOutputCallback func = (DisplayLinkOutputCallback) callbackHandle.Target!;
CVDisplayLink delegateDisplayLink = new CVDisplayLink(displayLink, false);
#if NET
return func (delegateDisplayLink,
ref System.Runtime.CompilerServices.Unsafe.AsRef<CVTimeStamp> (inNow),
ref System.Runtime.CompilerServices.Unsafe.AsRef<CVTimeStamp> (inOutputTime),
flagsIn, ref System.Runtime.CompilerServices.Unsafe.AsRef<CVOptionFlags> (flagsOut));
#else
return func (delegateDisplayLink, ref inNow, ref inOutputTime, flagsIn, ref flagsOut);
#endif
}
#if NET
[DllImport (Constants.CoreVideoLibrary)]
extern static unsafe CVReturn CVDisplayLinkSetOutputCallback (IntPtr displayLink, delegate* unmanaged<IntPtr, CVTimeStamp*, CVTimeStamp*, CVOptionFlags, CVOptionFlags *, IntPtr, CVReturn> function, IntPtr userInfo);
#else
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVDisplayLinkSetOutputCallback (IntPtr displayLink, CVDisplayLinkOutputCallback function, IntPtr userInfo);
#endif
public CVReturn SetOutputCallback (DisplayLinkOutputCallback callback)
{
callbackHandle = GCHandle.Alloc (callback);
#if NET
unsafe {
CVReturn ret = CVDisplayLinkSetOutputCallback (this.Handle, &OutputCallback, GCHandle.ToIntPtr (callbackHandle));
return ret;
}
#else
CVReturn ret = CVDisplayLinkSetOutputCallback (this.Handle, static_OutputCallback, GCHandle.ToIntPtr (callbackHandle));
return ret;
#endif
}
#if NET

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

@ -146,15 +146,35 @@ namespace CoreVideo {
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
/* const void * CV_NULLABLE */ IntPtr baseAddress);
#if !NET
static CVPixelBufferReleaseBytesCallback releaseBytesCallback = new CVPixelBufferReleaseBytesCallback (ReleaseBytesCallback);
#endif
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleaseBytesCallback))]
#endif
static void ReleaseBytesCallback (IntPtr releaseRefCon, IntPtr baseAddress)
{
GCHandle handle = GCHandle.FromIntPtr (releaseRefCon);
handle.Free ();
}
#if NET
[DllImport (Constants.CoreVideoLibrary)]
static unsafe extern CVReturn CVPixelBufferCreateWithBytes (
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
/* size_t */ nint width,
/* size_t */ nint height,
/* OSType */ CVPixelFormatType pixelFormatType,
/* void * CV_NONNULL */ IntPtr baseAddress,
/* size_t */ nint bytesPerRow,
delegate* unmanaged<IntPtr, IntPtr, void> releaseCallback,
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut);// __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
#else
[DllImport (Constants.CoreVideoLibrary)]
static extern CVReturn CVPixelBufferCreateWithBytes (
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
@ -167,7 +187,7 @@ namespace CoreVideo {
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut);// __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
#endif
public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[] data, nint bytesPerRow, CVPixelBufferAttributes pixelBufferAttributes)
{
CVReturn status;
@ -187,7 +207,13 @@ namespace CoreVideo {
gchandle = GCHandle.Alloc (data, GCHandleType.Pinned); // This requires a pinned GCHandle, because unsafe code is scoped to the current block, and the address of the byte array will be used after this function returns.
#if NET
unsafe {
status = CVPixelBufferCreateWithBytes (IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject (), bytesPerRow, &ReleaseBytesCallback, GCHandle.ToIntPtr (gchandle), DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
}
#else
status = CVPixelBufferCreateWithBytes (IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject (), bytesPerRow, releaseBytesCallback, GCHandle.ToIntPtr (gchandle), DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
#endif
if (status != CVReturn.Success) {
gchandle.Free ();
@ -210,11 +236,11 @@ namespace CoreVideo {
/* size_t */ nint dataSize,
/* size_t */ nint numberOfPlanes,
/* const void* */IntPtr planeAddresses);
#if !NET
static CVPixelBufferReleasePlanarBytesCallback releasePlanarBytesCallback = new CVPixelBufferReleasePlanarBytesCallback (ReleasePlanarBytesCallback);
#endif
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleasePlanarBytesCallback))]
static void ReleasePlanarBytesCallback (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
static void ReleasePlanarBytesCallbackImpl (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
{
GCHandle handle = GCHandle.FromIntPtr (releaseRefCon);
PlaneData data = (PlaneData) handle.Target!;
@ -222,7 +248,36 @@ namespace CoreVideo {
data.dataHandles[i].Free ();
handle.Free ();
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallbackAttribute (typeof (CVPixelBufferReleasePlanarBytesCallback))]
#endif
static void ReleasePlanarBytesCallback (IntPtr releaseRefCon, IntPtr dataPtr, nint dataSize, nint numberOfPlanes, IntPtr planeAddresses)
{
ReleasePlanarBytesCallbackImpl (releaseRefCon, dataPtr, dataSize, numberOfPlanes, planeAddresses);
}
#if NET
[DllImport (Constants.CoreVideoLibrary)]
static unsafe extern CVReturn CVPixelBufferCreateWithPlanarBytes (
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
/* size_t */ nint width,
/* size_t */ nint height,
/* OSType */ CVPixelFormatType pixelFormatType,
/* void * CV_NULLABLE */ IntPtr dataPtr, /* pass a pointer to a plane descriptor block, or NULL /*
/* size_t */ nint dataSize, /* pass size if planes are contiguous, NULL if not */
/* size_t */ nint numberOfPlanes,
/* void *[] CV_NULLABLE */ IntPtr[] planeBaseAddress,
/* size_t[] */ nint [] planeWidth,
/* size_t[] */ nint [] planeHeight,
/* size_t[] */ nint [] planeBytesPerRow,
delegate* unmanaged<IntPtr, IntPtr, nint, nint, IntPtr, void>/* CV_NULLABLE */ releaseCallback,
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut); // __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
#else
[DllImport (Constants.CoreVideoLibrary)]
static extern CVReturn CVPixelBufferCreateWithPlanarBytes (
/* CFAllocatorRef CV_NULLABLE */ IntPtr allocator,
@ -240,6 +295,7 @@ namespace CoreVideo {
/* void * CV_NULLABLE */ IntPtr releaseRefCon,
/* CFDictionaryRef CV_NULLABLE */ IntPtr pixelBufferAttributes,
/* CV_RETURNS_RETAINED_PARAMETER CVPixelBufferRef CV_NULLABLE * CV_NONNULL */ out IntPtr pixelBufferOut); // __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_4_0);
#endif
public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[][] planes, nint[] planeWidths, nint[] planeHeights, nint[] planeBytesPerRow, CVPixelBufferAttributes pixelBufferAttributes)
{
@ -287,14 +343,24 @@ namespace CoreVideo {
data_handle = GCHandle.Alloc (data);
IntPtr data_handle_ptr = GCHandle.ToIntPtr (data_handle);
#if NET
unsafe {
status = CVPixelBufferCreateWithPlanarBytes (IntPtr.Zero,
width, height, pixelFormatType, IntPtr.Zero, 0,
planeCount, addresses, planeWidths, planeHeights, planeBytesPerRow,
&ReleasePlanarBytesCallback, data_handle_ptr,
DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
}
#else
status = CVPixelBufferCreateWithPlanarBytes (IntPtr.Zero,
width, height, pixelFormatType, IntPtr.Zero, 0,
planeCount, addresses, planeWidths, planeHeights, planeBytesPerRow,
releasePlanarBytesCallback, data_handle_ptr,
DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle);
#endif
if (status != CVReturn.Success) {
ReleasePlanarBytesCallback (data_handle_ptr, IntPtr.Zero, 0, 0, IntPtr.Zero);
ReleasePlanarBytesCallbackImpl (data_handle_ptr, IntPtr.Zero, 0, 0, IntPtr.Zero);
return null;
}

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

@ -10,6 +10,7 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
@ -19,6 +20,10 @@ using Foundation;
using Registrar;
#endif
#if !COREBUILD
using Xamarin.Bundler;
#endif
#if !NET
using NativeHandle = System.IntPtr;
#endif
@ -56,8 +61,8 @@ namespace ObjCRuntime {
for (int i = 0; i < map->assembly_count; i++) {
var ptr = Marshal.ReadIntPtr (map->assembly, i * IntPtr.Size);
Runtime.Registrar.SetAssemblyRegistered (Marshal.PtrToStringAuto (ptr));
var assembly = map->assemblies [i];
Runtime.Registrar.SetAssemblyRegistered (Marshal.PtrToStringAuto (assembly.name));
}
}
@ -292,27 +297,27 @@ namespace ObjCRuntime {
if ((token_reference & 0x1) == 0x1) {
// full token reference
var idx = (int) (token_reference >> 1);
var entry = map->full_token_references + (IntPtr.Size + 8) * idx;
var entry = map->full_token_references [idx];
// first compare what's most likely to fail (the type's metadata token)
var token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size + 4);
var token = entry.token;
type_token |= 0x02000000 /* TypeDef - the token type is explicit in the full token reference, but not present in the type_token argument, so we have to add it before comparing */;
if (type_token != token)
return false;
// then the module token
var module_token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size);
var module_token = entry.module_token;
if (mod_token != module_token)
return false;
// leave the assembly name for the end, since it's the most expensive comparison (string comparison)
assembly_name = Marshal.ReadIntPtr (entry);
assembly_name = map->assemblies [entry.assembly_index].name;
} else {
// packed token reference
if (token_reference >> 8 != type_token)
return false;
var assembly_index = (token_reference >> 1) & 0x7F;
assembly_name = Marshal.ReadIntPtr (map->assembly, (int) assembly_index * IntPtr.Size);
assembly_name = map->assemblies [(int) assembly_index].name;
}
return Runtime.StringEquals (assembly_name, asm_name);
@ -380,10 +385,11 @@ namespace ObjCRuntime {
internal unsafe static MemberInfo? ResolveFullTokenReference (uint token_reference)
{
// sizeof (MTFullTokenReference) = IntPtr.Size + 4 + 4
var entry = Runtime.options->RegistrationMap->full_token_references + (IntPtr.Size + 8) * (int) (token_reference >> 1);
var assembly_name = Marshal.ReadIntPtr (entry);
var module_token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size);
var token = (uint) Marshal.ReadInt32 (entry + IntPtr.Size + 4);
var idx = (int) (token_reference >> 1);
var entry = Runtime.options->RegistrationMap->full_token_references [idx];
var assembly_name = Runtime.options->RegistrationMap->assemblies [entry.assembly_index].name;
var module_token = entry.module_token;
var token = entry.token;
#if LOG_TYPELOAD
Console.WriteLine ($"ResolveFullTokenReference (0x{token_reference:X}) assembly name: {assembly_name} module token: 0x{module_token:X} token: 0x{token:X}.");
@ -430,7 +436,7 @@ namespace ObjCRuntime {
Console.WriteLine ($"ResolveTokenReference (0x{token_reference:X}) assembly index: {assembly_index} token: 0x{token:X}.");
#endif
var assembly_name = Marshal.ReadIntPtr (map->assembly, (int) assembly_index * IntPtr.Size);
var assembly_name = map->assemblies [(int) assembly_index].name;
var assembly = ResolveAssembly (assembly_name);
var module = ResolveModule (assembly, 0x1);
@ -474,7 +480,65 @@ namespace ObjCRuntime {
throw ErrorHelper.CreateError (8020, $"Could not find the module with MetadataToken 0x{token:X} in the assembly {assembly}.");
}
// Restrict this code to desktop for now, which is where most of the problems with outdated generated static registrar code occur.
#if __MACOS__ || __MACCATALYST__
static bool? verify_static_registrar_code;
static object? verification_lock;
static Dictionary<IntPtr, object?>? verified_assemblies; // Use Dictionary instead of HashSet to avoid pulling in System.Core.dll.
unsafe static void VerifyStaticRegistrarCode (IntPtr assembly_name, Assembly assembly)
{
if (verify_static_registrar_code is null) {
verify_static_registrar_code = !string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE"));
verification_lock = new object ();
}
if (verify_static_registrar_code != true)
return;
lock (verification_lock!) {
if (verified_assemblies is null) {
verified_assemblies = new Dictionary<IntPtr, object?> (Runtime.IntPtrEqualityComparer);
} else if (verified_assemblies.ContainsKey (assembly_name)) {
return;
}
verified_assemblies [assembly_name] = null;
}
var map = Runtime.options->RegistrationMap;
if (map is null)
return;
for (var i = 0; i < map->assembly_count; i++) {
var entry = map->assemblies [i];
var name = Marshal.PtrToStringAuto (entry.name)!;
if (!Runtime.StringEquals (assembly_name, name))
continue;
try {
var mvid = Marshal.PtrToStringAuto (entry.mvid)!;
var runtime_mvid = assembly.ManifestModule.ModuleVersionId;
var registered_mvid = Guid.Parse (mvid);
if (registered_mvid == runtime_mvid)
continue;
throw ErrorHelper.CreateError (8044, Errors.MX8044 /* The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}. */, name, runtime_mvid, registered_mvid);
} catch (Exception e) {
throw ErrorHelper.CreateError (8043, e, Errors.MX8043 /* An exception occurred while validating the static registrar code for {0}: {1} */, name, e.Message);
}
}
}
#endif // __MACOS__ || __MACCATALYST__
static Assembly ResolveAssembly (IntPtr assembly_name)
{
if (TryResolveAssembly (assembly_name, out var asm)) {
#if __MACOS__ || __MACCATALYST__
VerifyStaticRegistrarCode (assembly_name, asm);
#endif
return asm;
}
throw ErrorHelper.CreateError (8019, $"Could not find the assembly {Marshal.PtrToStringAuto (assembly_name)} in the loaded assemblies.");
}
static bool TryResolveAssembly (IntPtr assembly_name, [NotNullWhen (true)] out Assembly? assembly)
{
// Find the assembly. We've already loaded all the assemblies that contain registered types, so just look at those assemblies.
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies ()) {
@ -482,12 +546,14 @@ namespace ObjCRuntime {
continue;
#if LOG_TYPELOAD
Console.WriteLine ($"ResolveAssembly (0x{assembly_name:X}): {asm.FullName}.");
Console.WriteLine ($"TryResolveAssembly (0x{assembly_name:X}): {asm.FullName}.");
#endif
return asm;
assembly = asm;
return true;
}
throw ErrorHelper.CreateError (8019, $"Could not find the assembly {Marshal.PtrToStringAuto (assembly_name)} in the loaded assemblies.");
assembly = null;
return false;
}
internal unsafe static uint GetTokenReference (Type type, bool throw_exception = true)
@ -514,7 +580,7 @@ namespace ObjCRuntime {
// Find the assembly index in our list of registered assemblies.
int assembly_index = -1;
for (int i = 0; i < map->assembly_count; i++) {
var name_ptr = Marshal.ReadIntPtr (map->assembly, (int) i * IntPtr.Size);
var name_ptr = map->assemblies [(int) i].name;
if (Runtime.StringEquals (name_ptr, asm_name)) {
assembly_index = i;
break;
@ -542,15 +608,16 @@ namespace ObjCRuntime {
{
var map = Runtime.options->RegistrationMap;
for (int i = 0; i < map->full_token_reference_count; i++) {
var ptr = map->full_token_references + (i * (IntPtr.Size + 8));
var asm_ptr = Marshal.ReadIntPtr (ptr);
var token = Marshal.ReadInt32 (ptr + IntPtr.Size + 4);
var ftr = map->full_token_references [i];
var token = ftr.token;
if (token != metadata_token)
continue;
var mod_token = Marshal.ReadInt32 (ptr + IntPtr.Size);
var mod_token = ftr.module_token;
if (mod_token != module_token)
continue;
if (!Runtime.StringEquals (asm_ptr, assembly_name))
var assembly_index = ftr.assembly_index;
var assembly = map->assemblies [assembly_index];
if (!Runtime.StringEquals (assembly.name, assembly_name))
continue;
return ((uint) i << 1) + 1;

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

@ -419,6 +419,13 @@ namespace ObjCRuntime {
if (obj == null)
return;
var structType = obj.GetType ();
// Unwrap enums, Marshal.StructureToPtr complains they're not blittable (https://github.com/xamarin/xamarin-macios/issues/15744)
if (structType.IsEnum) {
structType = Enum.GetUnderlyingType (structType);
obj = Convert.ChangeType (obj, structType);
}
if (obj is bool b) {
// Only write a single byte for bools
Marshal.WriteByte (ptr, b ? (byte) 1 : (byte) 0);

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

@ -55,9 +55,9 @@ namespace ObjCRuntime {
#pragma warning disable 649 // Field 'X' is never assigned to, and will always have its default value
internal unsafe struct MTRegistrationMap {
public IntPtr assembly;
public MTAssembly *assemblies;
public MTClassMap *map;
public IntPtr full_token_references; /* array of MTFullTokenReference */
public MTFullTokenReference *full_token_references;
public MTManagedClassMap* skipped_map;
public MTProtocolWrapperMap* protocol_wrapper_map;
public MTProtocolMap protocol_map;
@ -78,6 +78,13 @@ namespace ObjCRuntime {
UserType = 2,
}
[StructLayout (LayoutKind.Sequential, Pack = 1)]
internal unsafe struct MTFullTokenReference {
public uint assembly_index;
public uint module_token;
public uint token;
}
[StructLayout (LayoutKind.Sequential, Pack = 1)]
internal struct MTClassMap {
public IntPtr handle;
@ -104,6 +111,12 @@ namespace ObjCRuntime {
public IntPtr* protocols;
}
[StructLayout (LayoutKind.Sequential, Pack = 1)]
internal unsafe struct MTAssembly {
public IntPtr name;
public IntPtr mvid;
}
/* Keep Delegates, Trampolines and InitializationOptions in sync with monotouch-glue.m */
#pragma warning disable 649 // Field 'X' is never assigned to, and will always have its default value
internal struct Trampolines {

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

@ -11,11 +11,10 @@
#if !WATCH
using System;
using System.Collections;
using System.Collections.Generic;
using Foundation;
using ObjCRuntime;
using CoreGraphics;
#nullable enable
namespace UIKit {
@ -41,9 +40,9 @@ namespace UIKit {
{
var copyOfRecognizers = recognizers;
var savedHandle = Handle;
recognizers = null;
recognizers = new Dictionary<Token, IntPtr> ();
if (copyOfRecognizers == null)
if (copyOfRecognizers.Count == 0)
return;
DangerousRetain (savedHandle);
@ -80,12 +79,12 @@ namespace UIKit {
[Register ("__UIGestureRecognizerGenericCB")]
internal class Callback<T> : Token where T: UIGestureRecognizer {
Action<T> action;
internal Callback (Action<T> action)
{
this.action = action;
}
[Export ("target:")]
[Preserve (Conditional = true)]
public void Activated (T sender) => action (sender);
@ -168,7 +167,10 @@ namespace UIKit {
//
public IEnumerable<Token> GetTargets ()
{
return (IEnumerable<Token>) recognizers?.Keys ?? Array.Empty<Token> ();
var keys = recognizers?.Keys;
if (keys is null)
return Array.Empty<Token> ();
return (IEnumerable<Token>) keys;
}
}

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

@ -0,0 +1,63 @@
using System;
using System.Runtime.InteropServices;
using Foundation;
using ObjCRuntime;
namespace MySimpleApp
{
public class Program
{
static int Main (string[] args)
{
Console.WriteLine (Environment.GetEnvironmentVariable ("MAGIC_WORD"));
#if INCLUDED_ADDITIONAL_CODE
GC.KeepAlive (typeof (AdditionalClass));
#endif
return StaticRegistrarValidationTest ();
}
static int StaticRegistrarValidationTest ()
{
try {
using var obj = new SomeObj ();
obj.Whatever ();
xamarin_IntPtr_objc_msgSend_IntPtr_ref_IntPtr_exception (obj.Handle, Selector.GetHandle ("whatever"), IntPtr.Zero, IntPtr.Zero, out var gchandle);
Console.WriteLine ($"GCH: {gchandle}");
if (gchandle != IntPtr.Zero) {
var gch = GCHandle.FromIntPtr (gchandle);
var exc = (Exception) gch.Target;
gch.Free ();
throw exc;
}
return 1; // We're not supposed to get here
} catch (Exception e) {
Console.WriteLine ($"E: {e}");
if (e.Message.Contains ("The assembly MyRegistrarApp has been modified since the app was built, invalidating the generated static registrar code."))
return 0;
return 2;
}
}
[DllImport ("__Internal")]
static extern IntPtr xamarin_IntPtr_objc_msgSend_IntPtr_ref_IntPtr_exception (IntPtr handle, IntPtr selector, IntPtr p0, IntPtr p1, out IntPtr gchandle);
}
public class SomeObj : NSObject
{
[Export ("whatever")]
public IntPtr Whatever ()
{
return new IntPtr (0xdeadf00d);
}
}
public class DeadClass {} // Some code for the linker to remove
#if INCLUDED_ADDITIONAL_CODE
public class AdditionalClass {
}
#endif
}

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

@ -0,0 +1 @@
include ../shared.mk

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

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

@ -0,0 +1,2 @@
TOP=../../..
include $(TOP)/tests/common/shared-dotnet-test.mk

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

@ -0,0 +1 @@
include ../shared.mk

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-ios</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

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

@ -0,0 +1 @@
include ../shared.mk

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-macos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

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

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<OutputType>Exe</OutputType>
<ApplicationTitle>MyRegistrarApp</ApplicationTitle>
<ApplicationId>com.xamarin.myregistrarapp</ApplicationId>
<ExcludeNUnitLiteReference>true</ExcludeNUnitLiteReference>
<ExcludeTouchUnitReference>true</ExcludeTouchUnitReference>
<DefineConstants>$(DefineConstants);$(AdditionalDefineConstants)</DefineConstants>
</PropertyGroup>
<Import Project="../../common/shared-dotnet.csproj" />
<ItemGroup>
<Compile Include="../*.cs" />
</ItemGroup>
</Project>

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

@ -0,0 +1,3 @@
TOP=../../../..
TESTNAME=MyRegistrarApp
include $(TOP)/tests/common/shared-dotnet.mk

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

@ -0,0 +1 @@
include ../shared.mk

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-tvos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

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

@ -34,7 +34,7 @@ class MainClass {
// Capture the current time
var timestamp = DateTime.UtcNow;
File.WriteAllText (mainFile, mainContents + "\n");
File.WriteAllText (mainFile, mainContents);
// Build again
rv = DotNet.AssertBuild (project_path, properties);

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

@ -982,5 +982,19 @@ namespace Xamarin.Tests {
Assert.That (errors [0].Message, Does.Contain ("Error loading Entitlements.plist template 'Entitlements.plist'"), "Message");
}
}
[TestCase (ApplePlatform.MacOSX, "osx-arm64")]
public void CustomAppBundleDir (ApplePlatform platform, string runtimeIdentifiers)
{
var project = "MySimpleApp";
Configuration.IgnoreIfIgnoredPlatform (platform);
var project_path = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifiers, platform: platform, out var appPath);
Clean (project_path);
var properties = GetDefaultProperties (runtimeIdentifiers);
var customAppBundleDir = Path.Combine (Cache.CreateTemporaryDirectory (), project + ".app");
properties ["AppBundleDir"] = customAppBundleDir;
var result = DotNet.AssertBuild (project_path, properties);
}
}
}

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

@ -0,0 +1,55 @@
namespace Xamarin.Tests {
[TestFixture]
public class RegistrarTest : TestBaseClass
{
[TestCase (ApplePlatform.MacCatalyst, true)]
[TestCase (ApplePlatform.MacOSX, true)]
[TestCase (ApplePlatform.iOS, false)]
[TestCase (ApplePlatform.TVOS, false)]
public void InvalidStaticRegistrarValidation (ApplePlatform platform, bool validated)
{
var project = "MyRegistrarApp";
var configuration = "Debug";
var runtimeIdentifiers = GetDefaultRuntimeIdentifier (platform);
Configuration.IgnoreIfIgnoredPlatform (platform);
var projectPath = GetProjectPath (project, platform: platform);
Clean (projectPath);
var properties = GetDefaultProperties ();
properties ["Registrar"] = "static";
// enable the linker (so that the main assembly is modified)
properties ["LinkMode"] = "full";
properties ["MtouchLink"] = "full";
DotNet.AssertBuild (projectPath, properties);
var appDir = GetAppPath (projectPath, platform, runtimeIdentifiers, configuration);
var asmDir = Path.Combine (appDir, GetRelativeAssemblyDirectory (platform));
var appExecutable = Path.Combine (asmDir, project + ".dll");
// Save the first version of the main assembly in memory
var firstAssembly = File.ReadAllBytes (appExecutable);
// Build again, including additional code
properties ["AdditionalDefineConstants"] = "INCLUDED_ADDITIONAL_CODE";
DotNet.AssertBuild (projectPath, properties);
// Revert to the original version of the main assembly
File.WriteAllBytes (appExecutable, firstAssembly);
Environment.SetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE", "1");
try {
if (validated) {
ExecuteProjectWithMagicWordAndAssert (projectPath, platform, runtimeIdentifiers);
} else if (CanExecute (platform, runtimeIdentifiers)) {
var rv = base.Execute (GetNativeExecutable (platform, appDir), out var output, out _);
Assert.AreEqual (1, rv.ExitCode, "Expected no validation");
}
} finally {
Environment.SetEnvironmentVariable ("XAMARIN_VALIDATE_STATIC_REGISTRAR_CODE", null);
}
}
}
}

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

@ -40,9 +40,24 @@ namespace Xamarin.Tests {
}
protected string GetAppPath (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
{
return Path.Combine (GetBinDir (projectPath, platform, runtimeIdentifiers, configuration), Path.GetFileNameWithoutExtension (projectPath) + ".app");
}
protected string GetBinDir (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
{
return GetBinOrObjDir ("bin", projectPath, platform, runtimeIdentifiers, configuration);
}
protected string GetObjDir (string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
{
return GetBinOrObjDir ("obj", projectPath, platform, runtimeIdentifiers, configuration);
}
protected string GetBinOrObjDir (string binOrObj, string projectPath, ApplePlatform platform, string runtimeIdentifiers, string configuration = "Debug")
{
var appPathRuntimeIdentifier = runtimeIdentifiers.IndexOf (';') >= 0 ? "" : runtimeIdentifiers;
return Path.Combine (Path.GetDirectoryName (projectPath)!, "bin", configuration, platform.ToFramework (), appPathRuntimeIdentifier, Path.GetFileNameWithoutExtension (projectPath) + ".app");
return Path.Combine (Path.GetDirectoryName (projectPath)!, binOrObj, configuration, platform.ToFramework (), appPathRuntimeIdentifier);
}
protected string GetOutputPath (string project, string? subdir, string runtimeIdentifiers, ApplePlatform platform, string configuration = "Debug")
@ -275,20 +290,25 @@ namespace Xamarin.Tests {
}
protected void ExecuteWithMagicWordAndAssert (string executable)
{
var rv = Execute (executable, out var output, out string magicWord);
Assert.That (output.ToString (), Does.Contain (magicWord), "Contains magic word");
Assert.AreEqual (0, rv.ExitCode, "ExitCode");
}
protected Execution Execute (string executable, out StringBuilder output, out string magicWord)
{
if (!File.Exists (executable))
throw new FileNotFoundException ($"The executable '{executable}' does not exists.");
var magicWord = Guid.NewGuid ().ToString ();
magicWord = Guid.NewGuid ().ToString ();
var env = new Dictionary<string, string?> {
{ "MAGIC_WORD", magicWord },
{ "DYLD_FALLBACK_LIBRARY_PATH", null }, // VSMac might set this, which may cause tests to crash.
};
var output = new StringBuilder ();
var rv = Execution.RunWithStringBuildersAsync (executable, Array.Empty<string> (), environment: env, standardOutput: output, standardError: output, timeout: TimeSpan.FromSeconds (15)).Result;
Assert.That (output.ToString (), Does.Contain (magicWord), "Contains magic word");
Assert.AreEqual (0, rv.ExitCode, "ExitCode");
output = new StringBuilder ();
return Execution.RunWithStringBuildersAsync (executable, Array.Empty<string> (), environment: env, standardOutput: output, standardError: output, timeout: TimeSpan.FromSeconds (15)).Result;
}
public static StringBuilder AssertExecute (string executable, params string[] arguments)

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

@ -263,8 +263,23 @@ namespace ObjCRuntime
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
public extern static void void_objc_msgSend_NSRange_out_NSRange_ref_NSRange (IntPtr receiver, IntPtr selector, _LongNSRange p1, out _LongNSRange p2, ref _LongNSRange p3);
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
public extern static void void_objc_msgSend_ref_byte_ref_sbyte_ref_short_ref_ushort_ref_int_ref_uint_ref_long_ref_ulong (IntPtr receiver, IntPtr selector, ref EnumB b, ref EnumSB sb, ref EnumS s, ref EnumUS us, ref EnumI i, ref EnumUI ui, ref EnumL l, ref EnumUL ul);
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
public extern static void void_objc_msgSend_out_byte_out_sbyte_out_short_out_ushort_out_int_out_uint_out_long_out_ulong (IntPtr receiver, IntPtr selector, out EnumB b, out EnumSB sb, out EnumS s, out EnumUS us, out EnumI i, out EnumUI ui, out EnumL l, out EnumUL ul);
}
public enum EnumB : byte { a, b = 10 };
public enum EnumSB : sbyte { a, b = 11 };
public enum EnumS : short { a, b = 12 };
public enum EnumUS : ushort { a, b = 13 };
public enum EnumI : int { a, b = 14 };
public enum EnumUI : uint { a, b = 15 };
public enum EnumL : long { a, b = 16 };
public enum EnumUL : ulong { a, b = 17 };
public struct _LongNSRange {
public long Location;
public long Length;

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

@ -1694,21 +1694,38 @@ namespace MonoTouchFixtures.ObjCRuntime {
}
[Register ("UnderlyingEnumValues")]
class UnderlyingEnumValues : NSObject
internal class UnderlyingEnumValues : NSObject
{
enum B : byte { a };
enum SB : sbyte { a };
enum S : short { a };
enum US : ushort { a };
enum I : int { a };
enum UI : uint { a };
enum L : long { a };
enum UL : ulong { a };
[Export ("Foo:a:b:c:d:e:f:g:h")]
void Foo (B b, SB sb, S s, US us, I i, UI ui, L l, UL ul)
void Foo (EnumB b, EnumSB sb, EnumS s, EnumUS us, EnumI i, EnumUI ui, EnumL l, EnumUL ul)
{
}
[Export ("ByRef:a:b:c:d:e:f:g:")]
void ByRef (ref EnumB b, ref EnumSB sb, ref EnumS s, ref EnumUS us, ref EnumI i, ref EnumUI ui, ref EnumL l, ref EnumUL ul)
{
b = EnumB.b;
sb = EnumSB.b;
s = EnumS.b;
us = EnumUS.b;
i = EnumI.b;
ui = EnumUI.b;
l = EnumL.b;
ul = EnumUL.b;
}
[Export ("Out:a:b:c:d:e:f:g:")]
void Out (out EnumB b, out EnumSB sb, out EnumS s, out EnumUS us, out EnumI i, out EnumUI ui, out EnumL l, out EnumUL ul)
{
b = EnumB.b;
sb = EnumSB.b;
s = EnumS.b;
us = EnumUS.b;
i = EnumI.b;
ui = EnumUI.b;
l = EnumL.b;
ul = EnumUL.b;
}
}
// It should be possible to export two identically named nested types.
@ -5456,6 +5473,43 @@ namespace MonoTouchFixtures.ObjCRuntime {
}
}
#endif // !__WATCHOS__ && !__TVOS__
[Test]
public void RefEnumValues ()
{
EnumB b = 0;
EnumSB sb = 0;
EnumS s = 0;
EnumUS us = 0;
EnumI i = 0;
EnumUI ui = 0;
EnumL l = 0;
EnumUL ul = 0;
using (var obj = new UnderlyingEnumValues ()) {
b = 0; sb = 0; s = 0; us = 0; i = 0; ui = 0; l = 0; ul = 0;
Messaging.void_objc_msgSend_ref_byte_ref_sbyte_ref_short_ref_ushort_ref_int_ref_uint_ref_long_ref_ulong (obj.Handle, Selector.GetHandle ("ByRef:a:b:c:d:e:f:g:"), ref b, ref sb, ref s, ref us, ref i, ref ui, ref l, ref ul);
Assert.AreEqual (EnumB.b, b, "ref: B");
Assert.AreEqual (EnumSB.b, sb, "ref: SB");
Assert.AreEqual (EnumS.b, s, "ref: S");
Assert.AreEqual (EnumUS.b, us, "ref: US");
Assert.AreEqual (EnumI.b, i, "ref: I");
Assert.AreEqual (EnumUI.b, ui, "ref: UI");
Assert.AreEqual (EnumL.b, l, "ref: L");
Assert.AreEqual (EnumUL.b, ul, "ref: UL");
b = 0; sb = 0; s = 0; us = 0; i = 0; ui = 0; l = 0; ul = 0;
Messaging.void_objc_msgSend_out_byte_out_sbyte_out_short_out_ushort_out_int_out_uint_out_long_out_ulong (obj.Handle, Selector.GetHandle ("Out:a:b:c:d:e:f:g:"), out b, out sb, out s, out us, out i, out ui, out l, out ul);
Assert.AreEqual (EnumB.b, b, "out: B");
Assert.AreEqual (EnumSB.b, sb, "out: SB");
Assert.AreEqual (EnumS.b, s, "out: S");
Assert.AreEqual (EnumUS.b, us, "out: US");
Assert.AreEqual (EnumI.b, i, "out: I");
Assert.AreEqual (EnumUI.b, ui, "out: UI");
Assert.AreEqual (EnumL.b, l, "out: L");
Assert.AreEqual (EnumUL.b, ul, "out: UL");
}
}
}
#if !__WATCHOS__

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

@ -2118,7 +2118,7 @@ namespace Registrar {
AutoIndentStringBuilder full_token_references = new AutoIndentStringBuilder ();
uint full_token_reference_count;
List<string> registered_assemblies = new List<string> ();
List<(AssemblyDefinition Assembly, string Name)> registered_assemblies = new List<(AssemblyDefinition Assembly, string Name)> ();
bool IsPlatformType (TypeReference type)
{
@ -2853,9 +2853,9 @@ namespace Registrar {
if (string.IsNullOrEmpty (single_assembly)) {
foreach (var assembly in GetAssemblies ())
registered_assemblies.Add (GetAssemblyName (assembly));
registered_assemblies.Add (new (assembly, GetAssemblyName (assembly)));
} else {
registered_assemblies.Add (single_assembly);
registered_assemblies.Add (new (GetAssemblies ().Single (v => GetAssemblyName (v) == single_assembly), single_assembly));
}
foreach (var @class in allTypes) {
@ -3154,22 +3154,24 @@ namespace Registrar {
map.AppendLine ();
}
map.AppendLine ("static const char *__xamarin_registration_assemblies []= {");
map.AppendLine ("static const MTAssembly __xamarin_registration_assemblies [] = {");
int count = 0;
foreach (var assembly in registered_assemblies) {
count++;
if (count > 1)
map.AppendLine (", ");
map.Append ("\"");
map.Append (assembly);
map.Append ("\"");
map.Append ("{ \"");
map.Append (assembly.Name);
map.Append ("\", \"");
map.Append (assembly.Assembly.MainModule.Mvid.ToString ());
map.Append ("\" }");
}
map.AppendLine ();
map.AppendLine ("};");
map.AppendLine ();
if (full_token_reference_count > 0) {
map.AppendLine ("static const struct MTFullTokenReference __xamarin_token_references [] = {");
map.AppendLine ("static const MTFullTokenReference __xamarin_token_references [] = {");
map.AppendLine (full_token_references);
map.AppendLine ("};");
map.AppendLine ();
@ -4876,7 +4878,13 @@ namespace Registrar {
default:
throw ErrorHelper.CreateError (99, Errors.MX0099, $"unsupported tokentype ({member.MetadataToken.TokenType}) for {member.FullName}");
}
full_token_references.AppendFormat ("\t\t{{ /* #{3} = 0x{4:X} */ \"{0}\", 0x{1:X}, 0x{2:X} }},\n", GetAssemblyName (member.Module.Assembly), member.Module.MetadataToken.ToUInt32 (), member.MetadataToken.ToUInt32 (), full_token_reference_count, rv);
var assemblyIndex = registered_assemblies.FindIndex (v => v.Assembly == member.Module.Assembly);
var assemblyName = registered_assemblies [assemblyIndex].Name;
var moduleToken = member.Module.MetadataToken.ToUInt32 ();
var moduleName = member.Module.Name;
var memberToken = member.MetadataToken.ToUInt32 ();
var memberName = member.FullName;
full_token_references.Append ($"\t\t{{ /* #{full_token_reference_count} = 0x{rv:X} */ {assemblyIndex} /* {assemblyName} */, 0x{moduleToken:X} /* {moduleName} */, 0x{memberToken:X} /* {memberName} */ }},\n");
return rv;
}
@ -4908,7 +4916,7 @@ namespace Registrar {
/* The assembly must be a registered one, and only within the first 128 assemblies */
var assembly_name = GetAssemblyName (member.Module.Assembly);
var index = registered_assemblies.IndexOf (assembly_name);
var index = registered_assemblies.FindIndex (v => v.Name == assembly_name);
if (index < 0 || index > 127)
return CreateFullTokenReference (member);

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

@ -140,22 +140,27 @@ Describe "TestResults tests" {
New-Item -Path "$testDirectory/TestSummary-prefixintrospection-2" -Name "TestSummary.md" -Value "SummaryE" -Force
New-Item -Path "$testDirectory/TestSummary-prefixmtouch-3" -Name "TestSummary.md" -Value "SummaryF" -Force
$labels = "linker;introspection".Split(";")
$labels = @("linker", "introspection", "monotouch-test")
$testResults = New-TestSummaryResults -Path "$testDirectory" -Labels $labels -TestPrefix "prefix"
Remove-Item -Path $testDirectory -Recurse
$testResults.count | Should -Be 2
$testResults.count | Should -Be $labels.count
$testResults[0].Label | Should -Be "linker"
$testResults[0].Context | Should -Be " - linker"
$testResults[0].ResultsPath | Should -Be "$Env:PWD/subdir/TestSummary-prefixlinker-200/TestSummary.md"
$testResults[0].ResultsPath | Should -Be "$(get-location)/subdir/TestSummary-prefixlinker-200/TestSummary.md"
$testResults[0].TestsJobStatus | Should -Be "yay"
$testResults[1].Label | Should -Be "introspection"
$testResults[1].Context | Should -Be " - introspection"
$testResults[1].ResultsPath | Should -Be "$Env:PWD/subdir/TestSummary-prefixintrospection-2/TestSummary.md"
$testResults[1].ResultsPath | Should -Be "$(get-location)/subdir/TestSummary-prefixintrospection-2/TestSummary.md"
$testResults[1].TestsJobStatus | Should -Be "nay"
$testResults[2].Label | Should -Be "monotouch_test"
$testResults[2].Context | Should -Be " - monotouch_test"
$testResults[2].ResultsPath | Should -Be "./subdir/TestSummary-prefixmonotouch_test-1/TestSummary.md"
$testResults[2].TestsJobStatus | Should -Be ""
}
}

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

@ -28,14 +28,14 @@ class TestResults {
}
[bool] IsSuccess() {
Write-Debug "\t$($this.Label) - IsSuccess()"
Write-Debug "`t$($this.Label) - IsSuccess()"
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
Write-Debug "\t\t$($this.Label) - Found special label $($this.Label), checking only status."
Write-Debug "`t`t$($this.Label) - Found special label $($this.Label), checking only status."
return $this.TestsJobStatus -eq "Succeeded"
} else {
$hasResultsPath = Test-Path $this.ResultsPath -PathType Leaf
Write-Debug "\t\t$($this.Label) - Path $($this.ResultsPath) exits? $hasResultsPath"
Write-Debug "\t\t$($this.Label) - Test status: $($this.TestsJobStatus)"
Write-Debug "`t`t$($this.Label) - Path $($this.ResultsPath) exists? $hasResultsPath"
Write-Debug "`t`t$($this.Label) - Test status: $($this.TestsJobStatus)"
return $hasResultsPath -and ($this.TestsJobStatus -eq "Succeeded")
}
}
@ -91,13 +91,13 @@ class TestResults {
[object] GetPassedTests() {
Write-Debug "$($this.Label) - GetPassedTests()"
if ($this.Passed -eq -1 -or $this.Failed -eq -1) {
Write-Debug "\t$($this.Label) - Calculate results."
Write-Debug "`t$($this.Label) - Calculate results."
# the result file is diff if the result was a success or not
if ($this.IsSuccess()) {
Write-Debug "$($this.Label) - IsSuccess() => TRUE"
Write-Debug "`t$($this.Label) - IsSuccess() => TRUE"
$this.Failed = 0
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
Write-Debug "\t\t$($this.Label) - Found special label $($this.Label), adding a single pass."
Write-Debug "`t`t$($this.Label) - Found special label $($this.Label), adding a single pass."
$this.Passed = 1
} else {
# in this case, the file contains a single line with the number and the following
@ -106,27 +106,26 @@ class TestResults {
$regexp = "(# :tada: All )(?<passed>[0-9]+)( tests passed :tada:)"
$content = Get-Content $this.ResultsPath | Select -First 1
if ($content -eq "# No tests selected.") {
Write-Debug "\t\tNo tests selected"
Write-Debug "`t`tNo tests selected"
$this.Passed = 0
} elseif ($content -match $regexp) {
Write-Debug "Did match regexp"
$this.Passed = $matches.passed -as [int]
Write-Debug "Passed tests count: $($this.Passed)"
Write-Debug "`tPassed tests count: $($this.Passed)"
} else {
throw "Unknown result pattern '$content'"
throw "Unable to understand the test result '$content' for test '$($this.Label)'"
}
}
} else {
Write-Debug "IsSuccess() => FALSE"
Write-Debug "`t$($this.Label) - IsSuccess() => FALSE"
$fileIsPresent = Test-Path $this.ResultsPath -PathType Leaf
if ($this.TestsJobStatus -eq "" -or -not (Test-Path $this.ResultsPath -PathType Leaf)) {
Write-Debug "\t\tTests job status: $($this.TestsJobStatus)"
Write-Debug "\t\tNot Found results path: $fileIsPresent"
Write-Debug "`t`tTests job status: $($this.TestsJobStatus)"
Write-Debug "`t`tNot Found results path: $fileIsPresent"
$this.Passed = -2
$this.Failed = -2
} else {
if ($this.NotTestSummaryLabels.Contains($this.Label)) {
Write-Debug "\t\tFound special label $($this.Label), adding a single fail."
Write-Debug "`t`tFound special label $($this.Label), adding a single fail."
$this.Passed = 0
$this.Failed = 1
} else {
@ -160,20 +159,24 @@ class TestResults {
# <summary>4 tests failed, 144 tests passed.</summary>
$regexp = "(\<summary\>)(?<failed>[0-9]+)( tests failed, )(?<passed>[0-9]+)( tests passed\.\</summary\>)"
if ($content -match $regexp) {
Write-Debug "\t\tMatched regexpt."
Write-Debug "`t`tMatched regexpt."
$this.Passed = $matches.passed -as [int]
$this.Failed = $matches.failed -as [int]
Write-Debug "\t\tPassed: $($this.Passed) Failed: $($this.Failed)"
} else {
throw "Unknown result pattern '$content'"
Write-Debug "`t`tAdding a single fail because unexpected <summary> contents found: $($content)"
$this.Passed = 0
$this.Failed = 1
}
} else {
throw "Unknown result pattern of a failed test"
Write-Debug "`t`tNo <summary> found, adding a single fail"
$this.Passed = 0
$this.Failed = 1
}
}
}
}
}
Write-Debug "`t$($this.Label) - Passed: $($this.Passed) Failed: $($this.Failed)"
return [PSCustomObject]@{
Passed = $this.Passed
Failed = $this.Failed
@ -241,7 +244,7 @@ class ParallelTestsResults {
}
# we return the patterns we already know
if ($failedTests -eq 0) {
if ($failedTests -eq 0 -and $crashedTests -eq 0) {
return ":tada: All $passedTests tests passed :tada:"
} else {
return "$crashedTests tests crashed, $failedTests tests failed, $passedTests tests passed."
@ -307,8 +310,8 @@ class ParallelTestsResults {
} else {
# create a detail per test result with the name of the test and will contain the exact summary
$stringBuilder.AppendLine("<summary>$($result.Failed) tests failed, $($result.Passed) tests passed.</summary>")
$stringBuilder.AppendLine("<details>")
if (Test-Path -Path $r.ResultsPath -PathType Leaf) {
$stringBuilder.AppendLine("<details>")
$stringBuilder.AppendLine("")
$foundTests = $false
foreach ($line in Get-Content -Path $r.ResultsPath)
@ -321,12 +324,8 @@ class ParallelTestsResults {
}
}
}
$stringBuilder.AppendLine("</details>")
$stringBuilder.AppendLine("")
} else {
$stringBuilder.AppendLine("<details>")
$stringBuilder.AppendLine(" Test has no summary file.")
$stringBuilder.AppendLine("</details>")
}
$stringBuilder.AppendLine("</details>")
$stringBuilder.AppendLine("")
@ -402,7 +401,7 @@ function New-TestSummaryResults {
$environmentVariable = "TESTS_JOBSTATUS_$($label.ToUpper())"
$status = [Environment]::GetEnvironmentVariable($environmentVariable)
Write-Host "Test results for $label is '$status'"
Write-Debug "Test results for $label is '$status'"
$testSummaryDirectoryExpression = "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports\TestSummary-$TestPrefix$label-*"
@ -411,7 +410,10 @@ function New-TestSummaryResults {
$testSummaryDirectories = Get-ChildItem -Path $Path -Directory -Filter $directoryFilter
if ($testSummaryDirectories.length -eq 0) {
Write-Host "WARNING: Found no directories matching $directoryFilter for label $label"
Write-Debug "WARNING: Found no directories matching $directoryFilter for label $label and prefix $TestPrefix"
$testSummaryPath = Join-Path $Path "TestSummary-$TestPrefix$label-1" "TestSummary.md"
$result = New-TestResults -Path $testSummaryPath -Status $status -Label $label -Context "$Env:CONTEXT - $label" -Attempt 1
$testResults += $result
continue
}
@ -436,10 +438,10 @@ function New-TestSummaryResults {
$testAttemptPath = $testSummaryDirectory.Name
$testSummaryPath = Join-Path $testAttemptPath "TestSummary.md"
Write-Host "Found "$attemptDirectories.count" directories, selected $testSummaryDirectory and final path is $testSummaryPath"
Write-Debug "Found $($attemptDirectories.count) directories, selected $testSummaryDirectory and final path is $testSummaryPath"
if (-not (Test-Path -Path $testSummaryPath -PathType Leaf)) {
Write-Host "WARNING: Path $testSummaryPath does not exist"
Write-Debug "WARNING: Path $testSummaryPath does not exist"
}
$result = New-TestResults -Path $testSummaryPath -Status $status -Label $label -Context "$Env:CONTEXT - $label" -Attempt $testAttempt

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

@ -49,7 +49,7 @@ steps:
inputs:
dropServiceURI: 'https://devdiv.artifacts.visualstudio.com/DefaultCollection'
dropMetadataContainerName: 'DropMetadata-ChangeDetection'
buildNumber: 'xamarin-macios/detected-changes/$(Build.BuildNumber)/$(Build.BuildId)'
buildNumber: 'xamarin-macios/detected-changes/$(Build.BuildNumber)/$(Build.BuildId)-$(System.JobAttempt)'
sourcePath: '$(System.DefaultWorkingDirectory)/change-detection/results/'
detailedLog: true
usePat: true
@ -57,7 +57,7 @@ steps:
# Process the github comment and publish it
- pwsh: |
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
$vsdropsChangeDetectionPrefix = "https://vsdrop.corp.microsoft.com/file/v1/xamarin-macios/detected-changes/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID/;/"
$vsdropsChangeDetectionPrefix = "https://vsdrop.corp.microsoft.com/file/v1/xamarin-macios/detected-changes/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID-$Env:SYSTEM_JOBATTEMPT/;/"
$rootDirectory = Join-Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY" "change-detection" "results"

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

@ -19,6 +19,6 @@ steps:
displayName: 'Publish Artifact: build-binlogs'
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/build-binlogs
artifactName: build-binlogs-$(Build.BuildId)
artifactName: build-binlogs-$(Build.BuildId)-$(System.JobAttempt)
continueOnError: true
condition: and(succeededOrFailed(), contains(variables['configuration.BuildNugets'], 'True'))

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

@ -49,24 +49,28 @@ steps:
# build a message with all the content of all tests, to do so, we get the labels and to pass them to pwsh we do a join with ;
# as the separator
- pwsh: |
$vsdropsIndex="$Env:VSDROPSPREFIX/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID/"
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
$DebugPreference = "Continue" # enable debug messages
try {
$vsdropsIndex="$Env:VSDROPSPREFIX/$Env:BUILD_BUILDNUMBER/$Env:BUILD_BUILDID-$Env:SYSTEM_JOBATTEMPT/"
Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1
$DebugPreference = "Continue" # enable debug messages
$labels = "$Env:LABELS".Split(";")
$labels = "$Env:LABELS".Split(";")
$testResults = New-TestSummaryResults -Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports" -Labels $labels -TestPrefix "${{ parameters.testPrefix }}"
$testResults = New-TestSummaryResults -Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\Reports" -Labels $labels -TestPrefix "${{ parameters.testPrefix }}"
$parallelResults = New-ParallelTestsResults -Results $testResults -Context "$Env:CONTEXT" -TestPrefix "${{ parameters.testPrefix }}" -VSDropsIndex $vsdropsIndex
$success = $parallelResults.IsSuccess()
$emoji = ":rocket:"
if (-not $success) {
Set-PipelineResult -Status partiallySucceeded
$emoji = ":fire:"
}
$parallelResults = New-ParallelTestsResults -Results $testResults -Context "$Env:CONTEXT" -TestPrefix "${{ parameters.testPrefix }}" -VSDropsIndex $vsdropsIndex
$success = $parallelResults.IsSuccess()
$emoji = ":rocket:"
if (-not $success) {
Set-PipelineResult -Status partiallySucceeded
$emoji = ":fire:"
}
$gihubComments = New-GitHubCommentsObject -Org "xamarin" -Repo "xamarin-macios" -Token $Env:GITHUB_TOKEN -Hash $Env:GIT_HASH -Debug
$result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults)
$gihubComments = New-GitHubCommentsObject -Org "xamarin" -Repo "xamarin-macios" -Token $Env:GITHUB_TOKEN -Hash $Env:GIT_HASH -Debug
$result = $gihubComments.NewCommentFromObject("Test results", $emoji, $parallelResults)
} catch {
New-GitHubComment -Header "Failed to compute test summaries on $Env:CONTEXT" -Emoji ":fire:" -Description "Failed to compute test summaries: $_."
}
env:
LABELS: ${{ join(';', parameters.simTestsConfigurations) }}
BUILD_REVISION: $(Build.SourceVersion)

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

@ -175,7 +175,7 @@ steps:
echo "##vso[task.setvariable variable=TESTS_BOT;isOutput=true]$AGENT_NAME"
# uri used to create the vsdrops index using full uri
export VSDROPS_URI="$VSDROPSPREFIX/$BUILD_BUILDNUMBER/$BUILD_BUILDID/$PARAMETERS_TESTPREFIX;/tests/"
export VSDROPS_URI="$VSDROPSPREFIX/$BUILD_BUILDNUMBER/$BUILD_BUILDID-$SYSTEM_JOBATTEMPT/$PARAMETERS_TESTPREFIX;/tests/"
# assume something is going to fail
echo "##vso[task.setvariable variable=TESTS_JOBSTATUS;isOutput=true]Failed"
@ -218,7 +218,7 @@ steps:
displayName: 'Publish Artifact: Simulator diagnostic info'
inputs:
targetPath: $(System.DefaultWorkingDirectory)/diagnostic-sim-output
artifactName: diagnostic-simulator-info-$(Build.BuildId)-${{ parameters.label }}
artifactName: diagnostic-simulator-info-$(Build.BuildId)-$(System.JobAttempt)-${{ parameters.label }}
condition: and(eq(variables['system.debug'], true), succeededOrFailed())
continueOnError: true

18
tools/mtouch/Errors.designer.cs сгенерированный
Просмотреть файл

@ -4113,5 +4113,23 @@ namespace Xamarin.Bundler {
return ResourceManager.GetString("MX8042", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An exception occurred while validating the static registrar code for {0}: {1}.
/// </summary>
public static string MX8043 {
get {
return ResourceManager.GetString("MX8043", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}..
/// </summary>
public static string MX8044 {
get {
return ResourceManager.GetString("MX8044", resourceCulture);
}
}
}
}

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

@ -2171,4 +2171,16 @@
1: exception info
</comment>
</data>
<data name="MX8043" xml:space="preserve">
<value>An exception occurred while validating the static registrar code for {0}: {1}</value>
<comment>
0: name of an assembly
1: exception info
</comment>
</data>
<data name="MX8044" xml:space="preserve">
<value>The assembly {0} has been modified since the app was built, invalidating the generated static registrar code. The MVID for the loaded assembly is {1}, while the MVID for the assembly the generated static registrar code corresponds to is {2}.</value>
</data>
</root>