Example #1
0
        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);
        }
Example #2
0
 public static void GetArrayDataReference_NonEmptyInput_ReturnsRefToFirstElement()
 {
     int[] theArray = new int[] { 10, 20, 30 };
     Assert.True(Unsafe.AreSame(ref theArray[0], ref MemoryMarshal.GetArrayDataReference(theArray)));
 }
Example #3
0
        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);
        }
Example #4
0
 /// <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);
 }
Example #6
0
 /// <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));
 }
Example #7
0
        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)));
 }
Example #9
0
 /// <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()));
 }
Example #10
0
    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>()));
    }
Example #11
0
    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())));
 }
Example #13
0
        //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);
        }
Example #14
0
        public void At()
        {
            Span <byte> span = stackalloc byte[] { 255, 255 };

            Assert.True(Unsafe.AreSame(ref span[1], ref span.At(1)));
        }