public static unsafe int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) { Debug.Assert(firstLength >= 0); Debug.Assert(secondLength >= 0); int lengthDelta = firstLength - secondLength; if (Unsafe.AreSame(ref first, ref second)) { goto Equal; } IntPtr minLength = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); IntPtr i = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations if ((byte *)minLength >= (byte *)(sizeof(UIntPtr) / sizeof(char))) { #if !netstandard11 if (Vector.IsHardwareAccelerated && (byte *)minLength >= (byte *)Vector <ushort> .Count) { IntPtr nLength = minLength - Vector <ushort> .Count; do { if (Unsafe.ReadUnaligned <Vector <ushort> >(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref first, i))) != Unsafe.ReadUnaligned <Vector <ushort> >(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref second, i)))) { break; } i += Vector <ushort> .Count; }while ((byte *)nLength >= (byte *)i); } #endif while ((byte *)minLength >= (byte *)(i + sizeof(UIntPtr) / sizeof(char))) { if (Unsafe.ReadUnaligned <UIntPtr>(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref first, i))) != Unsafe.ReadUnaligned <UIntPtr>(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref second, i)))) { break; } i += sizeof(UIntPtr) / sizeof(char); } } if (sizeof(UIntPtr) > sizeof(int) && (byte *)minLength >= (byte *)(i + sizeof(int) / sizeof(char))) { if (Unsafe.ReadUnaligned <int>(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref first, i))) == Unsafe.ReadUnaligned <int>(ref Unsafe.As <char, byte>(ref Unsafe.Add(ref second, i)))) { i += sizeof(int) / sizeof(char); } } while ((byte *)i < (byte *)minLength) { int result = Unsafe.Add(ref first, i).CompareTo(Unsafe.Add(ref second, i)); if (result != 0) { return(result); } i += 1; } Equal: return(lengthDelta); }
public static void GetArrayDataReference_NonEmptyInput_ReturnsRefToFirstElement() { int[] theArray = new int[] { 10, 20, 30 }; Assert.True(Unsafe.AreSame(ref theArray[0], ref MemoryMarshal.GetArrayDataReference(theArray))); }
public InteropAssemblyBuilder(AssemblyNameDefinition assemblyName, ModuleParameters moduleParams = null, string targetFramework = null) { Name = assemblyName; Namespace = assemblyName.Name; Statistics = new ReadOnlyDictionary <string, long>(_statistics); if (moduleParams == null) { moduleParams = DefaultModuleParameters; } // ReSharper disable once UnusedVariable var forceUnsafeToLoad = Unsafe.AreSame(ref assemblyName, ref assemblyName); //var loadedAsms = AppDomain.CurrentDomain.GetAssemblies(); //var loadedAsms = AssemblyResolver.KnownAssemblies; var asmResolver = new AssemblyResolver(); //var mdResolver = new MetadataResolver(asmResolver); var shadowAsmFilePath = Path.Combine(Directory.GetCurrentDirectory(), $"{BaseInteropAsmName}.dll"); File.Copy(BaseInteropAsmPath, shadowAsmFilePath); Assembly = AssemblyDefinition.ReadAssembly(shadowAsmFilePath, new ReaderParameters { InMemory = true, ReadWrite = true, ReadingMode = ReadingMode.Immediate, AssemblyResolver = asmResolver, //MetadataResolver = mdResolver, ReadSymbols = false, ApplyWindowsRuntimeProjections = false, //SymbolReaderProvider = null, //MetadataImporterProvider = null, //ReflectionImporterProvider = null, }); Assembly.Name = assemblyName; Module = Assembly.MainModule; ModuleName = $"{Name.Name}.dll"; Module.Name = ModuleName; if (EmitBoundsChecks) { ArgumentOutOfRangeCtor = ArgumentOutOfRangeCtorInfo.Import(Module); } if (EmitNullChecks) { ArgumentNullCtor = ArgumentNullCtorInfo.Import(Module); } NonVersionableAttribute = NonVersionableAttributeInfo? .GetCecilCustomAttribute(Module); FlagsAttribute = FlagsAttributeInfo .GetCecilCustomAttribute(Module); VoidPointerType = Module.TypeSystem.Void.MakePointerType(); MulticastDelegateType = typeof(MulticastDelegate).Import(Module); //var interopAsm = typeof(IHandle<>).Assembly; //var interopAsmName = interopAsm.GetName(); //var interopMod = interopAsm.ManifestModule; //Module.AssemblyReferences.Add(new AssemblyNameReference(interopAsmName.Name, interopAsmName.Version)); //Module.ModuleReferences.Add(new ModuleReference(interopAsmName.Name)); ITypedHandleType = typeof(ITypedHandle).Import(Module); IHandleGtd = typeof(IHandle <>).Import(Module); ITypedHandleGtd = typeof(ITypedHandle <>).Import(Module); HandleInt32Gtd = typeof(HandleInt32 <>).Import(Module); HandleUInt32Gtd = typeof(HandleUInt32 <>).Import(Module); HandleInt64Gtd = typeof(HandleInt64 <>).Import(Module); HandleUInt64Gtd = typeof(HandleUInt64 <>).Import(Module); HandleIntPtrGtd = typeof(HandleIntPtr <>).Import(Module); HandleUIntPtrGtd = typeof(HandleUIntPtr <>).Import(Module); SplitPointerGtd = typeof(SplitPointer <, ,>).Import(Module); BinderGeneratedAttributeType = typeof(BinderGeneratedAttribute).Import(Module); IUnmanagedFunctionPointerGtd = typeof(IUnmanagedFunctionPointer <>).Import(Module); TypeArrayOfSingularVoidPointer = new[] { VoidPointerType }; TypeArrayOfSingularUInt = new[] { Module.TypeSystem.UInt32 }; TypeArrayOfSingularULong = new[] { Module.TypeSystem.UInt64 }; IntegrateInteropTypes(Module.Types); if (targetFramework == null) { targetFramework = DefaultTargetFramework; } var asmCustAttrs = new[] { AttributeInfo.Create (() => new CompilationRelaxationsAttribute(8)), AttributeInfo.Create (() => new RuntimeCompatibilityAttribute { WrapNonExceptionThrows = true }), AttributeInfo.Create (() => new DebuggableAttribute(DebuggableAttribute.DebuggingModes.None)), AttributeInfo.Create (() => new TargetFrameworkAttribute(targetFramework) { FrameworkDisplayName = "" }), AttributeInfo.Create (() => new AssemblyCompanyAttribute("")), AttributeInfo.Create (() => new AssemblyConfigurationAttribute("Release")), AttributeInfo.Create (() => new AssemblyDescriptionAttribute($"Generated {Name.Name} Library")), AttributeInfo.Create (() => new AssemblyFileVersionAttribute(Name.Version.ToString())), AttributeInfo.Create (() => new AssemblyInformationalVersionAttribute(Name.Version.ToString())), AttributeInfo.Create (() => new AssemblyProductAttribute(Name.Name)), AttributeInfo.Create (() => new AssemblyTitleAttribute(Name.Name)), }.Select(ca => ca.GetCecilCustomAttribute(Module)); /* where the hell did this go... * var unverifiableCodeAttributeTypeRef = new TypeReference("System.Security", "UnverifiableCodeAttribute", * Module.TypeSystem.IntPtr.Resolve().Module, * Module.TypeSystem.CoreLibrary, false); * var unverifiableCodeAttributeTypeDef = unverifiableCodeAttributeTypeRef.Resolve(); * var unverifiableCodeAttributeCtor = unverifiableCodeAttributeTypeDef.GetConstructors().Single(); * * var unverifiableCodeAttribute = new CustomAttribute(unverifiableCodeAttributeCtor); */ while (Assembly.HasCustomAttributes) { Assembly.CustomAttributes.RemoveAt(0); } Assembly.CustomAttributes.Clear(); while (Module.HasCustomAttributes) { Module.CustomAttributes.RemoveAt(0); } Module.CustomAttributes.Clear(); foreach (var custAttr in asmCustAttrs) { Assembly.CustomAttributes.Add(custAttr); } //Module.CustomAttributes.Add(unverifiableCodeAttribute); /* * Assembly.SecurityDeclarations.Add(new SecurityDeclaration(SecurityAction.RequestMinimum) { * SecurityAttributes = { * // ... * } * }); * Module.CustomAttributes.Add( * AttributeInfo.Create(() => new UnverifiableCodeAttribute()) * .GetCecilCustomAttribute(Module)); */ MarshalTypeRef = typeof(Marshal).Import(Module); GetDelegateForFpMethodGtd = MarshalTypeRef.Resolve().GetMethods() .First(md => md.Name == "GetDelegateForFunctionPointer" && md.HasGenericParameters) .Import(Module); GetFpForDelegateMethodGtd = MarshalTypeRef.Resolve().GetMethods() .First(md => md.Name == "GetFunctionPointerForDelegate" && md.HasGenericParameters) .Import(Module); }
/// <summary> /// Checks to see if two spans point at the same memory. Note that /// this does *not* check to see if the *contents* are equal. /// </summary> public bool Equals(Span <T> other) { return((_length == other.Length) && (_length == 0 || Unsafe.AreSame(ref DangerousGetPinnableReference(), ref other.DangerousGetPinnableReference()))); }
private static void AssertRefSame(ref byte a, ref byte b, string msg) { Assert.True(Unsafe.AreSame(ref a, ref b), msg); }
/// <summary> /// Returns true if left and right point at the same memory and have the same length. Note that /// this does *not* check to see if the *contents* are equal. /// </summary> public static bool operator ==(ReadOnlySpan <T> left, ReadOnlySpan <T> right) { return(left._length == right._length && Unsafe.AreSame <T>(ref left._pointer.Value, ref right._pointer.Value)); }
public void GetReference() { var array = Enumerable.Range(0, 100).ToArray(); Assert.True(Unsafe.AreSame(ref array[0], ref array.GetReference())); }
public unsafe static bool IsNull(this Utf8Span span) { return(Unsafe.AreSame(ref Unsafe.AsRef <byte>(null), ref MemoryMarshal.GetReference(span.Bytes))); }
/// <summary> /// Returns true if left and right point at the same memory and have the same length. Note that /// this does *not* check to see if the *contents* are equal. /// </summary> public static bool operator ==(Span <T> left, Span <T> right) { return(left._length == right._length && Unsafe.AreSame <T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference())); }
private static bool TestInitBlk(ref byte dst, byte value, uint size) { Unsafe.InitBlock(ref dst, value, size); return(Unsafe.AreSame(ref dst, ref Unsafe.NullRef <byte>())); }
private static bool TestCpBlk(ref byte dst, ref byte src, uint size) { Unsafe.CopyBlock(ref dst, ref src, size); return(Unsafe.AreSame(ref dst, ref Unsafe.NullRef <byte>())); }
/// <summary> /// Checks to see if two spans point at the same memory. Note that /// this does *not* check to see if the *contents* are equal. /// </summary> public bool Equals(ReadOnlySpan <T> other) { return((_length == other.Length) && (_length == 0 || Unsafe.AreSame(ref GetRawPointer(), ref other.GetRawPointer()))); }
//Adapted from corefx repo static bool SequenceEqual <T>(ref T first, ref T second, int length) where T : struct { if (Unsafe.AreSame(ref first, ref second)) { return(true); } IntPtr offset = (IntPtr)0; T x; T y; while (length >= 8) { length -= 8; x = refAdd(ref first, offset + 0); y = refAdd(ref second, offset + 0); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 1); y = refAdd(ref second, offset + 1); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 2); y = refAdd(ref second, offset + 2); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 3); y = refAdd(ref second, offset + 3); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 4); y = refAdd(ref second, offset + 4); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 5); y = refAdd(ref second, offset + 5); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 6); y = refAdd(ref second, offset + 6); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 7); y = refAdd(ref second, offset + 7); if (gmath.neq(x, y)) { return(false); } offset += 8; } if (length >= 4) { length -= 4; x = refAdd(ref first, offset); y = refAdd(ref second, offset); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 1); y = refAdd(ref second, offset + 1); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 2); y = refAdd(ref second, offset + 2); if (gmath.neq(x, y)) { return(false); } x = refAdd(ref first, offset + 3); y = refAdd(ref second, offset + 3); if (gmath.neq(x, y)) { return(false); } offset += 4; } while (length > 0) { x = refAdd(ref first, offset); y = refAdd(ref second, offset); if (gmath.neq(x, y)) { return(false); } offset += 1; length--; } return(true); }
public void At() { Span <byte> span = stackalloc byte[] { 255, 255 }; Assert.True(Unsafe.AreSame(ref span[1], ref span.At(1))); }