using NUnit.Framework; using System; using System.Runtime.InteropServices; using Unity.Burst; using Unity.Mathematics; namespace Burst.Compiler.IL.Tests { /// /// Tests types /// [BurstCompile] internal class NotSupported { [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_OnlyStaticMethodsAllowed)] public int InstanceMethod() { return 1; } [TestCompiler(1, ExpectCompilerException = true, ExpectedDiagnosticIds = new[] { DiagnosticId.ERR_CallingManagedMethodNotSupported })] public static int TestDelegate(int data) { return ProcessData(i => i + 1, data); } private static int ProcessData(Func yo, int value) { return yo(value); } public struct HasMarshalAttribute { [MarshalAs(UnmanagedType.U1)] public bool A; } //[TestCompiler(ExpectCompilerException = true)] [TestCompiler] // Because MarshalAs is used in mathematics we cannot disable it for now public static void TestStructWithMarshalAs() { #pragma warning disable 0219 var x = new HasMarshalAttribute(); #pragma warning restore 0219 } public struct HasMarshalAsSysIntAttribute { [MarshalAs(UnmanagedType.SysInt)] public bool A; } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_MarshalAsOnFieldNotSupported)] public static void TestStructWithMarshalAsSysInt() { #pragma warning disable 0219 var x = new HasMarshalAsSysIntAttribute(); #pragma warning restore 0219 } [TestCompiler(42, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_MarshalAsOnParameterNotSupported)] public static void TestMethodWithMarshalAsParameter([MarshalAs(UnmanagedType.I8)] int x) { } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_MarshalAsOnReturnTypeNotSupported)] [return: MarshalAs(UnmanagedType.I8)] public static int TestMethodWithMarshalAsReturnType() { return 42; } private static float3 a = new float3(1, 2, 3); [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoadingFromNonReadonlyStaticFieldNotSupported)] public static bool TestStaticLoad() { var cmp = a == new float3(1, 2, 3); return cmp.x && cmp.y && cmp.z; } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoadingFromManagedNonReadonlyStaticFieldNotSupported)] public static void TestStaticStore() { a.x = 42; } private interface ISomething { void DoSomething(); } private struct Something : ISomething { public byte A; public void DoSomething() { A = 42; } } private static ISomething something = new Something { A = 13 }; [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoadingFromManagedNonReadonlyStaticFieldNotSupported)] public static void TestStaticInterfaceStore() { something.DoSomething(); } private static int i = 42; [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_LoadingFromNonReadonlyStaticFieldNotSupported)] public static int TestStaticIntLoad() { return i; } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionStsfldNotSupported)] public static void TestStaticIntStore() { i = 13; } public delegate char CharbyValueDelegate(char c); #if BURST_TESTS_ONLY [BurstCompile] #endif public static char CharbyValue(char c) { return c; } public struct CharbyValueFunc : IFunctionPointerProvider { public FunctionPointer FunctionPointer; public object FromIntPtr(IntPtr ptr) { return new CharbyValueFunc() { FunctionPointer = new FunctionPointer(ptr) }; } } [TestCompiler(nameof(CharbyValue), 0x1234, ExpectCompilerException = true, ExpectedDiagnosticIds = new[] { DiagnosticId.ERR_TypeNotBlittableForFunctionPointer, DiagnosticId.ERR_StructsWithNonUnicodeCharsNotSupported })] public static int TestCharbyValue(ref CharbyValueFunc fp, int i) { var c = (char)i; return fp.FunctionPointer.Invoke(c); } struct Halfs { public static readonly half3 h3_h = new half3(new half(42.0f)); public static readonly half3 h3_d = new half3(0.5); public static readonly half3 h3_v2s = new half3(new half2(new half(1.0f), new half(2.0f)), new half(0.5f)); public static readonly half3 h3_sv2 = new half3(new half(0.5f), new half2(new half(1.0f), new half(2.0f))); public static readonly half3 h3_v3 = new half3(new half(0.5f), new half(42.0f), new half(13.0f)); } [TestCompiler] public static float TestStaticHalf3() { var result = (float3)Halfs.h3_h + Halfs.h3_d + Halfs.h3_v2s + Halfs.h3_sv2 + Halfs.h3_v3; return result.x + result.y + result.z; } [TestCompiler(42, 13, ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_AssertTypeNotSupported)] public static void TestAreEqual(int a, int b) { Assert.AreEqual(a, b, "unsupported", new object[0]); } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_InstructionLdtokenTypeNotSupported)] public static bool TestTypeof() { return typeof(int).IsPrimitive; } public class AwfulClass { public int Foo; } public struct BetterStruct { public int Foo; } public struct MixedStaticInits { public static readonly AwfulClass AC = new AwfulClass { Foo = 42 }; public static readonly BetterStruct BS = new BetterStruct { Foo = 42 }; } [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticIds = new[] { DiagnosticId.ERR_InstructionNewobjWithManagedTypeNotSupported, DiagnosticId.ERR_ManagedStaticConstructor })] public static int TestMixedStaticInits() { return MixedStaticInits.BS.Foo; } public struct StaticArrayWrapper { private const int ArrayLength = 4; public static readonly int[] StaticArray = new int[4]; static StaticArrayWrapper() { for (int i = 0; i < ArrayLength; ++i) { StaticArray[i] = i; } } } [TestCompiler] public unsafe static int TestStaticArrayWrapper() { return StaticArrayWrapper.StaticArray[0]; } class NestedArrayHolder { public static readonly int4[][] SomeOffsetThing = { new[] {new int4(0), new int4(0, 0, 1, 0), new int4(0, 1, 0, 0), new int4(0, 1, 1, 0)}, new[] {new int4(0), new int4(1, 0, 0, 0), new int4(0, 0, 1, 0), new int4(1, 0, 1, 0)}, new[] {new int4(0), new int4(0, 1, 0, 0), new int4(1, 0, 0, 0), new int4(1, 1, 0, 0)}, }; } [TestCompiler] public unsafe static int TestNestedManagedArrays() { return NestedArrayHolder.SomeOffsetThing[0][0].x; } public static readonly int[,] SomeMultiDimensionalThing = new int[2, 4] { { 1, 2, 3, 4 }, { -1, -2, -3, -4 }, }; [TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticIds = new[] { DiagnosticId.ERR_ConstructorNotSupported, DiagnosticId.ERR_MultiDimensionalArrayUnsupported })] public static int TestMultiDimensionalArray() => SomeMultiDimensionalThing[1, 1]; } }