Firstborn/Library/PackageCache/com.unity.burst@1.7.3/Tests/Runtime/Shared/041-ControlFlowsTryCatchFin...
Schaken-Mods b486678290 Library -Artifacts
Library -Artifacts
2023-03-28 12:24:16 -05:00

286 lines
6.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace Burst.Compiler.IL.Tests
{
internal class ControlFlowsTryCatchFinally
{
[TestCompiler(-10)]
[TestCompiler(0)]
[TestCompiler(10)]
public static int TryFinallySimple(int i)
{
try
{
if (i == 0) // case 0
{
return 1;
}
else if (i > 0) // case 10
{
i = i * 2;
}
else
{
i = i * 3; // case -10
}
}
finally
{
i = i + 1;
}
return i; // both case 10 and -10
}
static void Oof()
{
}
[TestCompiler]
public static void TryFinallyFirstBlock()
{
try
{
}
finally
{
Oof();
}
}
[TestCompiler(-3)]
[TestCompiler(0)]
[TestCompiler(3)]
public static int TryFinallyComplex1(int i)
{
try
{
try
{
if (i == 0)
{
return i - 1;
}
i += 3;
}
finally
{
if (i == 0) // case i: -3
{
i = 1;
}
else
{
i = i * 10; // case i: 3
}
}
}
finally
{
i = i * 2; // both -3 and 3
}
return i + 1;
}
[TestCompiler(-10)]
[TestCompiler(0)] // case 0
[TestCompiler(10)]
public static int TryFinallyComplex2(int i)
{
// First block of nested try/catch
try
{
try
{
if (i == 0) // case 0
{
return i - 1;
}
i = i * 2;
}
finally
{
i++;
}
}
finally
{
i = i * 3;
}
// Second block of nested try/catch
try
{
i = i - 2;
try
{
if (i < 0) // case -10
{
return i * 5;
}
i += 3; // case 10
}
finally
{
i += 11;
}
}
finally
{
i = i * 3;
}
return i + 1; // case 10
}
[TestCompiler]
public static int TryUsingDispose()
{
using (var buffer = new CustomBuffer(32))
{
return buffer.Hash();
}
}
[TestCompiler]
public static int ForEachTryFinally()
{
int hashCode = 0;
foreach (var value in new RangeEnumerable(1, 100))
{
hashCode = (hashCode * 397) ^ value;
}
return hashCode;
}
[TestCompiler(ExpectCompilerException = true, ExpectedDiagnosticId = DiagnosticId.ERR_CatchConstructionNotSupported)]
public static int TryCatch()
{
try
{
return default(int);
}
catch (InvalidOperationException)
{
return 1;
}
}
private unsafe struct CustomBuffer : IDisposable
{
private readonly int _size;
private byte* _buffer;
public CustomBuffer(int size)
{
_size = size;
_buffer = (byte*)UnsafeUtility.Malloc(size, 4, Allocator.Persistent);
for (int i = 0; i < size; i++)
{
_buffer[i] = (byte)(i + 1);
}
}
public int Hash()
{
int hashCode = _size;
for (int i = 0; i < _size; i++)
{
hashCode = (hashCode * 397) ^ (byte)_buffer[i];
}
return hashCode;
}
public unsafe void Dispose()
{
if (_buffer != null)
{
UnsafeUtility.Free(_buffer, Allocator.Persistent);
_buffer = (byte*) 0;
}
}
}
private struct RangeEnumerable : IEnumerable<int>
{
private readonly int _from;
private readonly int _to;
public RangeEnumerable(int from, int to)
{
_from = @from;
_to = to;
}
public Enumerator GetEnumerator()
{
return new Enumerator();
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public struct Enumerator : IEnumerator<int>
{
private readonly int _from;
private readonly int _to;
public Enumerator(int from, int to)
{
_from = @from;
_to = to;
Current = -1;
}
public void Dispose()
{
// nothing to do
}
public bool MoveNext()
{
if (Current < 0)
{
Current = _from;
return true;
}
int nextIndex = Current + 1;
if (nextIndex >= _from && nextIndex <= _to)
{
Current = nextIndex;
return true;
}
return false;
}
public void Reset()
{
}
public int Current { get; private set; }
object IEnumerator.Current => Current;
}
}
}
}