initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,189 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Unity.Burst.Editor;
|
||||
using UnityEngine;
|
||||
using Unity.Burst;
|
||||
using Random = System.Random;
|
||||
|
||||
[TestFixture]
|
||||
public class BurstDisassemblerCoreInstructionTests
|
||||
{
|
||||
// Use chooser enum instead of BurstDisassembler.AsmKind because of accessibility level.
|
||||
public enum Chooser
|
||||
{
|
||||
ARM,
|
||||
INTEL,
|
||||
LLVMIR,
|
||||
Wasm
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(Chooser.ARM)]
|
||||
[TestCase(Chooser.INTEL)]
|
||||
// [TestCase(Chooser.LLVMIR)]
|
||||
[TestCase(Chooser.Wasm)]
|
||||
public void TestInfo(Chooser provider)
|
||||
{
|
||||
BurstDisassembler.AsmTokenKindProvider tokenProvider;
|
||||
switch (provider)
|
||||
{
|
||||
case Chooser.ARM:
|
||||
tokenProvider = BurstDisassembler.ARM64AsmTokenKindProvider.Instance;
|
||||
break;
|
||||
case Chooser.INTEL:
|
||||
tokenProvider = BurstDisassembler.X86AsmTokenKindProvider.Instance;
|
||||
break;
|
||||
case Chooser.Wasm:
|
||||
tokenProvider = BurstDisassembler.WasmAsmTokenKindProvider.Instance;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Oops you forgot to add a switch case in the test *quirky smiley*.");
|
||||
}
|
||||
|
||||
|
||||
var tokenProviderT = typeof(BurstDisassembler.AsmTokenKindProvider);
|
||||
|
||||
var field = tokenProviderT.GetField("_tokenKinds",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
Assert.NotNull(field, "Could not find _tokenKinds field in AsmTokenKindProvider");
|
||||
|
||||
var allTokens = (Dictionary<StringSlice, BurstDisassembler.AsmTokenKind>)field.GetValue(tokenProvider);
|
||||
|
||||
var tokensToTest =
|
||||
from tok in allTokens.Keys
|
||||
where allTokens.TryGetValue(tok, out var kind)
|
||||
&& kind != BurstDisassembler.AsmTokenKind.Qualifier
|
||||
&& kind != BurstDisassembler.AsmTokenKind.Register
|
||||
select tok.ToString();
|
||||
|
||||
var count = 0;
|
||||
foreach (var token in tokensToTest)
|
||||
{
|
||||
var res = false;
|
||||
switch (provider)
|
||||
{
|
||||
case Chooser.ARM:
|
||||
res = BurstDisassembler.ARM64InstructionInfo.GetARM64Info(token, out var _);
|
||||
break;
|
||||
case Chooser.INTEL:
|
||||
res = BurstDisassembler.X86AsmInstructionInfo.GetX86InstructionInfo(token, out var _);
|
||||
break;
|
||||
case Chooser.LLVMIR:
|
||||
res = BurstDisassembler.LLVMIRInstructionInfo.GetLLVMIRInfo(token, out var _);
|
||||
break;
|
||||
case Chooser.Wasm:
|
||||
res = BurstDisassembler.WasmInstructionInfo.GetWasmInfo(token, out var _);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
{
|
||||
Debug.Log($"Token \"{token}\" from {provider} does not have information associated.");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Assert.Zero(count, $"{provider.ToString()} is missing information for {count} token(s).");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether all instructions in available burst jobs are displayed correctly.
|
||||
/// </summary>
|
||||
[Test]
|
||||
[TestCase(Chooser.ARM)]
|
||||
[TestCase(Chooser.INTEL)]
|
||||
[TestCase(Chooser.Wasm)]
|
||||
public void TestInstructionsPresent(Chooser asmKind)
|
||||
{
|
||||
BurstTargetCpu targetCpu;
|
||||
BurstDisassembler.AsmKind targetKind;
|
||||
switch (asmKind)
|
||||
{
|
||||
case Chooser.INTEL:
|
||||
targetCpu = BurstTargetCpu.X64_SSE4;
|
||||
targetKind = BurstDisassembler.AsmKind.Intel;
|
||||
break;
|
||||
case Chooser.ARM:
|
||||
targetCpu = BurstTargetCpu.ARMV7A_NEON32;
|
||||
targetKind = BurstDisassembler.AsmKind.ARM;
|
||||
break;
|
||||
default: // WASM as LLVMIR is not tested.
|
||||
targetCpu = BurstTargetCpu.WASM32;
|
||||
targetKind = BurstDisassembler.AsmKind.Wasm;
|
||||
break;
|
||||
}
|
||||
|
||||
// Find all possible burst compile targets.
|
||||
var jobList = BurstReflection.FindExecuteMethods(
|
||||
BurstReflection.EditorAssembliesThatCanPossiblyContainJobs,
|
||||
BurstReflectionAssemblyOptions.None).CompileTargets;
|
||||
|
||||
var missingInstructions = new Dictionary<string, string>();
|
||||
var disassembler = new BurstDisassembler();
|
||||
foreach (var target in jobList)
|
||||
{
|
||||
// Get disassembly of target.
|
||||
var options = new StringBuilder();
|
||||
|
||||
target.Options.TryGetOptions(target.JobType, true, out var defaultOptions);
|
||||
options.AppendLine(defaultOptions);
|
||||
// Disables the 2 current warnings generated from code (since they clutter up the inspector display)
|
||||
// BC1370 - throw inside code not guarded with ConditionalSafetyCheck attribute
|
||||
// BC1322 - loop intrinsic on loop that has been optimised away
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDisableWarnings, "BC1370;BC1322")}");
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, Enum.GetNames(typeof(BurstTargetCpu))[(int)targetCpu])}");
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDebug, "0")}");
|
||||
|
||||
var baseOptions = options.ToString();
|
||||
var append = BurstInspectorGUI.GetDisasmOptions()[(int)DisassemblyKind.Asm];
|
||||
|
||||
// Setup disAssembler with the job:
|
||||
var text = BurstInspectorGUI.GetDisassembly(target.Method, baseOptions + append);
|
||||
|
||||
// Bail out if there was a Burst compiler error, because we'll have all sorts of unexpected tokens.
|
||||
if (BurstInspectorGUI.IsBurstError(text))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
text = text.TrimStart('\n');
|
||||
Assert.IsTrue(disassembler.Initialize(text, targetKind, true, false), "Could not initialize disassembler.");
|
||||
|
||||
// Get all tokens labeled as AsmTokenKind.Identifier that do not start with '.' nor ends on ':'.
|
||||
// If this number exceeds 0 we are missing instructions (I believe).
|
||||
const int INSTRUCTION_PRE_PADDING = 8;
|
||||
var tokens =
|
||||
(from tok in disassembler.Tokens
|
||||
where tok.Kind == BurstDisassembler.AsmTokenKind.Identifier
|
||||
&& !disassembler.GetTokenAsText(tok).StartsWith(".")
|
||||
&& !disassembler.GetTokenAsText(tok).EndsWith(":")
|
||||
&& text[tok.Position - INSTRUCTION_PRE_PADDING - 1] == '\n'
|
||||
select tok).ToList();
|
||||
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (missingInstructions.ContainsKey(token.ToString(text)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
missingInstructions.Add(token.ToString(text), target.GetDisplayName());
|
||||
}
|
||||
}
|
||||
// Convey result.
|
||||
if (missingInstructions.Count > 0)
|
||||
{
|
||||
foreach (var itm in missingInstructions)
|
||||
{
|
||||
var token = itm.Key;
|
||||
var name = itm.Value;
|
||||
Debug.Log($"Token \"{token}\" was not recognised as instruction for {targetKind} (Found in job {name}).");
|
||||
}
|
||||
Assert.Fail($"{missingInstructions.Count} missing instructions, see log. Add missing instructions and call both this test and {nameof(TestInfo)}.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c68d1e883c8136a89133cc095391d26b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,383 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Burst;
|
||||
using Unity.Burst.Editor;
|
||||
using UnityEditorInternal;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class BurstDisassemblerTests
|
||||
{
|
||||
private BurstDisassembler _disassembler;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_disassembler = new BurstDisassembler();
|
||||
}
|
||||
|
||||
private static string GetThisFilePath([CallerFilePath] string path = null) => path;
|
||||
|
||||
// A Test behaves as an ordinary method
|
||||
[Test]
|
||||
public void GetBlockIdxFromTextIdxTest()
|
||||
{
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
|
||||
Assert.IsTrue(_disassembler.Initialize(
|
||||
File.ReadAllText(Path.Combine(thisPath, "burstTestTarget.txt")),
|
||||
BurstDisassembler.AsmKind.Intel,
|
||||
false,
|
||||
false));
|
||||
|
||||
for (int blockIdx = 0; blockIdx < _disassembler.Blocks.Count; blockIdx++)
|
||||
{
|
||||
int blockStart = 0;
|
||||
for (int i = 0; i < blockIdx; i++)
|
||||
{
|
||||
blockStart += _disassembler.GetOrRenderBlockToText(i).Length;
|
||||
}
|
||||
|
||||
var blockStr = _disassembler.GetOrRenderBlockToText(blockIdx);
|
||||
int blockEnd = blockStart + blockStr.Length - 1;
|
||||
|
||||
Assert.AreEqual((blockIdx, blockStart, blockEnd),
|
||||
_disassembler.GetBlockIdxFromTextIdx(blockStart + 1),
|
||||
$"Block index was wrong for block with label {blockStr.Substring(0, blockStr.IndexOf('\n'))}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InstantiateRegistersUsedTest()
|
||||
{
|
||||
Assert.IsTrue(_disassembler.Initialize(simpleAssembly, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
var regsUsed = _disassembler._registersUsedAtLine;
|
||||
|
||||
// Match against expected:
|
||||
var expectedLines = from l in expected select l.lineNr;
|
||||
|
||||
var failed = expectedLines.Except(regsUsed._linesRegisters.Keys);
|
||||
failed = failed.Concat(regsUsed._linesRegisters.Keys.Except(expectedLines)).Distinct();
|
||||
if (failed.Any())
|
||||
{
|
||||
// Not exact match
|
||||
foreach (var f in failed)
|
||||
{
|
||||
Debug.Log($"lineNumber {f} failed");
|
||||
}
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanRegisterListTest()
|
||||
{
|
||||
Assert.IsTrue(_disassembler.Initialize(simpleAssembly, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
var regs = new List<string> { "rcx", "ecx", "rax" };
|
||||
var output = _disassembler._registersUsedAtLine.CleanRegs(regs);
|
||||
|
||||
var expected = new List<string> { "rcx", "rax" };
|
||||
Assert.AreEqual(output, expected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IndexOfRegisterTest()
|
||||
{
|
||||
var assembly =
|
||||
"\n" +
|
||||
" nop\n" +
|
||||
" movsxd rcx, cx\n" +
|
||||
" mov rax, qword ptr [rbp - 16]";
|
||||
Assert.IsTrue(_disassembler.Initialize(assembly, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
string[,] regs =
|
||||
{
|
||||
{ "rcx", "cx" },
|
||||
{ "rax", "rbp" }
|
||||
};
|
||||
string[] lines =
|
||||
{
|
||||
" movsxd rcx, cx\n",
|
||||
" mov rax, qword ptr [rbp - 16]"
|
||||
};
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
|
||||
var reg = regs[i, 0];
|
||||
var asmLine = _disassembler.Lines[i+1];
|
||||
var output = _disassembler.GetRegisterTokenIndex(asmLine, reg);
|
||||
var regIdx = _disassembler.Tokens[output].AlignedPosition - _disassembler.Tokens[asmLine.TokenIndex].AlignedPosition;
|
||||
|
||||
var expected = line.IndexOf(reg) + 1;
|
||||
Assert.AreEqual(expected, regIdx, $"Failed for line \"{line}\"");
|
||||
|
||||
reg = regs[i, 1];
|
||||
output = _disassembler.GetRegisterTokenIndex(asmLine, reg, output + 1);
|
||||
regIdx = _disassembler.Tokens[output].AlignedPosition - _disassembler.Tokens[asmLine.TokenIndex].AlignedPosition;
|
||||
|
||||
expected = line.IndexOf(reg, expected + 1) + 1;
|
||||
Assert.AreEqual(expected, regIdx, $"Failed for line \"{line}\"");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("x86", new [] {"rdx","edx","dx","dl"}, "dl")]
|
||||
[TestCase("arm", new [] {"wsp", "sp"},"sp")]
|
||||
[TestCase("arm", new [] {"v0.2d", "s0", "q0", "h0", "d0", "b0"}, "b0")]
|
||||
[TestCase("arm", new [] {"w0","x0"}, "x0")]
|
||||
public void RegisterEqualityTest(string assemblyName, string[] assemblyLine, string register)
|
||||
{
|
||||
BurstDisassembler.AsmTokenKindProvider tokenProvider = BurstDisassembler.ARM64AsmTokenKindProvider.Instance;
|
||||
if (assemblyName == "x86")
|
||||
{
|
||||
tokenProvider = BurstDisassembler.X86AsmTokenKindProvider.Instance;
|
||||
}
|
||||
|
||||
foreach (var reg in assemblyLine)
|
||||
{
|
||||
Assert.IsTrue(tokenProvider.RegisterEqual(reg, register), $"{reg} == {register}");
|
||||
}
|
||||
|
||||
// Some special cases:
|
||||
tokenProvider = BurstDisassembler.ARM64AsmTokenKindProvider.Instance;
|
||||
|
||||
Assert.IsFalse(tokenProvider.RegisterEqual("w8", "x0"), $"w8 != x0");
|
||||
Assert.IsFalse(tokenProvider.RegisterEqual("w0", "q0"), "w0 != q0");
|
||||
Assert.IsFalse(tokenProvider.RegisterEqual("x0", "q0"), "x0 != q0");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisterEqualTest()
|
||||
{
|
||||
// Only tests for x86, as the others are trivial.
|
||||
Assert.IsTrue(_disassembler.Initialize(simpleAssembly, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
// Get all register strings:
|
||||
var tokenProvider = BurstDisassembler.X86AsmTokenKindProvider.Instance;
|
||||
var tokenProviderT = typeof(BurstDisassembler.AsmTokenKindProvider);
|
||||
|
||||
var field = tokenProviderT.GetField("_tokenKinds",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
Assert.NotNull(field, "Could not find _tokenKinds field in AsmTokenKindProvider");
|
||||
|
||||
var allTokens = (Dictionary<StringSlice, BurstDisassembler.AsmTokenKind>)field.GetValue(tokenProvider);
|
||||
|
||||
var tokensToTest =
|
||||
from tok in allTokens.Keys
|
||||
where allTokens.TryGetValue(tok, out var kind)
|
||||
&& kind == BurstDisassembler.AsmTokenKind.Register
|
||||
select tok.ToString();
|
||||
|
||||
// Test that equality works for all registers:
|
||||
try
|
||||
{
|
||||
foreach (var reg in tokensToTest)
|
||||
{
|
||||
// Simply check whether all registers are processable:
|
||||
tokenProvider.RegisterEqual(reg, "rax");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Assert.Fail($"Not all registers works for register equality (x86). {e}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InstructionAlignmentTest()
|
||||
{
|
||||
var assembly =
|
||||
"\n" + // newline as BurstDisassembler ignores first line
|
||||
" push rbp\n" +
|
||||
" .seh_pushreg rbp\n" +
|
||||
" sub rsp, 32\n";
|
||||
(int, char)[] expectedPositions =
|
||||
{
|
||||
(1,' '), (10, 'p'), (14, ' '), (24, 'r'), (27, '\n'),
|
||||
(28, ' '), (37, '.'), (49, ' '), (50, 'r'), (53, '\n'),
|
||||
(54, ' '), (63, 's'), (66, ' '), (77, 'r'), (80, ','), (82, '3'), (84, '\n')
|
||||
};
|
||||
|
||||
Assert.IsTrue(_disassembler.Initialize(assembly, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
var builder = new StringBuilder();
|
||||
for (int i = 0; i < _disassembler.Blocks.Count; i++)
|
||||
{
|
||||
var text = _disassembler.GetOrRenderBlockToTextUncached(i, false);
|
||||
builder.Append(text);
|
||||
}
|
||||
|
||||
var output = builder.ToString();
|
||||
|
||||
for (var i = 0; i < expectedPositions.Length; i++)
|
||||
{
|
||||
Assert.AreEqual(expectedPositions[i].Item1, _disassembler.Tokens[i].AlignedPosition);
|
||||
}
|
||||
|
||||
foreach (var (idx, c) in expectedPositions)
|
||||
{
|
||||
// -1 as token index for some reason aren't zero indexed.
|
||||
Assert.AreEqual(c, output[idx-1], $"Token position for index {idx} was wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void X86AsmTokenProviderSimdKindTest()
|
||||
{
|
||||
var tp = BurstDisassembler.X86AsmTokenKindProvider.Instance;
|
||||
BurstDisassembler.SIMDkind actual = tp.SimdKind(new StringSlice("vsqrtsd"));
|
||||
var expected = BurstDisassembler.SIMDkind.Scalar;
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
|
||||
actual = tp.SimdKind(new StringSlice("vroundpd"));
|
||||
expected = BurstDisassembler.SIMDkind.Packed;
|
||||
Assert.AreEqual(expected, actual);
|
||||
|
||||
actual = tp.SimdKind(new StringSlice("xsaves"));
|
||||
expected = BurstDisassembler.SIMDkind.Infrastructure;
|
||||
Assert.AreEqual(expected,actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ARMAsmTokenProviderSimdKindTest()
|
||||
{
|
||||
var tp = BurstDisassembler.ARM64AsmTokenKindProvider.Instance;
|
||||
|
||||
BurstDisassembler.SIMDkind actual = tp.SimdKind(new StringSlice("vaddw"));
|
||||
var expected = BurstDisassembler.SIMDkind.Scalar;
|
||||
Assert.AreEqual(expected, actual);
|
||||
|
||||
actual = tp.SimdKind(new StringSlice("vadd.i8"));
|
||||
expected = BurstDisassembler.SIMDkind.Packed;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
private string GetFirstColorTag(string line)
|
||||
{
|
||||
const string colorTag = "#XXXXXX";
|
||||
const string tag = "<color=";
|
||||
int idx = line.IndexOf('<');
|
||||
return line.Substring(idx + tag.Length, colorTag.Length);
|
||||
}
|
||||
|
||||
private const string ARMsimdAssembly =
|
||||
"\n" +
|
||||
" ldr r0, [sp, #12]\n" +
|
||||
" vldr s0, [sp, #20]\n" +
|
||||
" vstr s0, [sp, #4]\n" +
|
||||
" ldr r1, [sp, #24]\n" +
|
||||
" vldr s0, [sp, #4]\n" +
|
||||
" vmov s2, r0\n" +
|
||||
" vadd.f32 s0, s0, s2\n" +
|
||||
" vstr s0, [sp, #20]";
|
||||
|
||||
private const string X86SimdAssembly =
|
||||
"\n" +
|
||||
" mov rcx, qword ptr [rbp - 32]\n" +
|
||||
" vmovss xmm0, dword ptr [rbp - 12]\n" +
|
||||
" vmovss dword ptr [rbp - 40], xmm0\n" +
|
||||
" mov edx, dword ptr [rbp - 8]\n" +
|
||||
" call \"Unity.Collections.NativeArray`1<float>.get_Item(Unity.Collections.NativeArray`1<float>* this, int index) -> float_c303f72c9cc472e2ef84a442ead69ef2 from Unity.Burst.Editor.Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\"\n" +
|
||||
" vmovaps xmm1, xmm0\n" +
|
||||
" vmovss xmm0, dword ptr [rbp - 40]\n" +
|
||||
" vaddss xmm0, xmm0, xmm1\n" +
|
||||
" vmovss dword ptr [rbp - 12], xmm0\n" +
|
||||
" vzeroall";
|
||||
[Test]
|
||||
[TestCase(X86SimdAssembly, 0, BurstDisassembler.DarkColorInstructionSIMDScalar, 1)]
|
||||
[TestCase(X86SimdAssembly, 0, BurstDisassembler.DarkColorInstructionSIMDPacked, 5)]
|
||||
[TestCase(X86SimdAssembly, 0, BurstDisassembler.DarkColorInstructionSIMD, 9)]
|
||||
[TestCase(ARMsimdAssembly, 1, BurstDisassembler.DarkColorInstructionSIMDScalar, 1)]
|
||||
[TestCase(ARMsimdAssembly, 1, BurstDisassembler.DarkColorInstructionSIMDPacked, 6)]
|
||||
public void AssemblyColouringSmellTest(string asm, int asmkind, string colorTag, int lineIdx)
|
||||
{
|
||||
_disassembler.Initialize(asm, (BurstDisassembler.AsmKind)asmkind, true, true, true);
|
||||
var line = _disassembler.Lines[lineIdx];
|
||||
_disassembler._output.Clear();
|
||||
_disassembler.RenderLine(ref line, true);
|
||||
var lineString = _disassembler._output.ToString();
|
||||
|
||||
_disassembler._output.Clear();
|
||||
Assert.AreEqual(colorTag, GetFirstColorTag(lineString));
|
||||
}
|
||||
|
||||
private List<(int lineNr, List<string>)> expected = new List<(int lineNr, List<string>)>
|
||||
{
|
||||
(2, new List<string> { "rbp" }),
|
||||
(3, new List<string> { "rbp" }),
|
||||
(4, new List<string> { "rsp" }),
|
||||
(6, new List<string> { "rbp", "rsp" }),
|
||||
(7, new List<string> { "rbp" }),
|
||||
(11, new List<string> { "rsp" }),
|
||||
(12, new List<string> { "rbp" }),
|
||||
(26, new List<string> { "rbp" }),
|
||||
(27, new List<string> { "rbp" }),
|
||||
(28, new List<string> { "rsp" }),
|
||||
(30, new List<string> { "rbp", "rsp" }),
|
||||
(31, new List<string> { "rbp" }),
|
||||
(36, new List<string> { "rsp" }),
|
||||
(37, new List<string> { "rbp" }),
|
||||
};
|
||||
private string simpleAssembly =
|
||||
"\n" + // newline as BurstDisassembler ignores first line
|
||||
".Lfunc_begin0:\n" +
|
||||
".seh_proc 589a9d678dbb1201e550a054238fad11\n" +
|
||||
" push rbp\n" +
|
||||
" .seh_pushreg rbp\n" +
|
||||
" sub rsp, 32\n" +
|
||||
" .seh_stackalloc 32\n" +
|
||||
" lea rbp, [rsp + 32]\n" +
|
||||
" .seh_setframe rbp, 32\n" +
|
||||
" .seh_endprologue\n" +
|
||||
" call A.B.DoIt\n" +
|
||||
" nop\n" +
|
||||
" add rsp, 32\n" +
|
||||
" pop rbp\n" +
|
||||
" ret\n" +
|
||||
" .Lfunc_end0:\n" +
|
||||
" .seh_endproc\n" +
|
||||
" \n" +
|
||||
" .def burst.initialize;\n" +
|
||||
" .scl 2;\n" +
|
||||
" .type 32;\n" +
|
||||
" .endef\n" +
|
||||
" .globl burst.initialize\n" +
|
||||
" .p2align 4, 0x90\n" +
|
||||
" burst.initialize:\n" +
|
||||
" .Lfunc_begin1:\n" +
|
||||
" .seh_proc burst.initialize\n" +
|
||||
" push rbp\n" +
|
||||
" .seh_pushreg rbp\n" +
|
||||
" sub rsp, 32\n" +
|
||||
" .seh_stackalloc 32\n" +
|
||||
" lea rbp, [rsp + 32]\n" +
|
||||
" .seh_setframe rbp, 32\n" +
|
||||
" .seh_endprologue\n" +
|
||||
" call burst.initialize.externals\n" +
|
||||
" call burst.initialize.statics\n" +
|
||||
" nop\n" +
|
||||
" add rsp, 32\n" +
|
||||
" pop rbp\n" +
|
||||
" ret\n" +
|
||||
" .Lfunc_end1:\n" +
|
||||
" .seh_endproc\n" +
|
||||
" \n" +
|
||||
" .def burst.initialize.externals;\n" +
|
||||
" .scl 2;\n" +
|
||||
" .type 32;\n" +
|
||||
" .endef\n" +
|
||||
" .globl burst.initialize.externals\n" +
|
||||
" .p2align 4, 0x90";
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 35ff2f449e6f335cb4f69ebb36ecf3e5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,588 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Unity.Burst.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Collections;
|
||||
using Unity.Burst;
|
||||
using Unity.Jobs;
|
||||
|
||||
[TestFixture]
|
||||
[UnityPlatform(RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor)]
|
||||
public class BurstInspectorGUITests
|
||||
{
|
||||
private readonly WaitUntil _waitForInitialized =
|
||||
new WaitUntil(() => EditorWindow.GetWindow<BurstInspectorGUI>()._initialized);
|
||||
|
||||
private IEnumerator SelectJobAwaitLoad(string assemblyName)
|
||||
{
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>()._treeView.TrySelectByDisplayName(assemblyName);
|
||||
return new WaitUntil(() =>
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>()._textArea.IsTextSet(assemblyName)
|
||||
);
|
||||
}
|
||||
|
||||
[UnitySetUp]
|
||||
public IEnumerator SetUp()
|
||||
{
|
||||
// Close down window if it's open, to start with a fresh inspector.
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>().Close();
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>().Show();
|
||||
|
||||
// Make sure window is actually initialized before continuing.
|
||||
yield return _waitForInitialized;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TestInspectorOpenDuringDomainReloadDoesNotLogErrors()
|
||||
{
|
||||
// Show Inspector window
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>().Show();
|
||||
|
||||
Assert.IsTrue(EditorWindow.HasOpenInstances<BurstInspectorGUI>());
|
||||
|
||||
// Ask for domain reload
|
||||
EditorUtility.RequestScriptReload();
|
||||
|
||||
// Wait for the domain reload to be completed
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
Assert.IsTrue(EditorWindow.HasOpenInstances<BurstInspectorGUI>());
|
||||
|
||||
// Hide Inspector window
|
||||
EditorWindow.GetWindow<BurstInspectorGUI>().Close();
|
||||
|
||||
Assert.IsFalse(EditorWindow.HasOpenInstances<BurstInspectorGUI>());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator DisassemblerNotChangingUnexpectedlyTest()
|
||||
{
|
||||
const string jobName2 = "BurstReflectionTests.MyJob - (IJob)";
|
||||
const string jobName = "BurstInspectorGUITests.MyJob - (IJob)";
|
||||
|
||||
// Selecting a specific assembly.
|
||||
yield return SelectJobAwaitLoad(jobName);
|
||||
var window = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
try
|
||||
{
|
||||
// Sending event to set the displayname, to avoid it resetting _scrollPos because of target change.
|
||||
window.SendEvent(new Event()
|
||||
{
|
||||
type = EventType.Repaint,
|
||||
mousePosition = new Vector2(window.position.width / 2f, window.position.height / 2f)
|
||||
});
|
||||
yield return null;
|
||||
|
||||
// Doing actual test work:
|
||||
var prev = new BurstDisassemblerWithCopy(window._burstDisassembler);
|
||||
window.SendEvent(new Event()
|
||||
{
|
||||
type = EventType.Repaint,
|
||||
mousePosition = new Vector2(window.position.width / 2f, window.position.height / 2f)
|
||||
});
|
||||
yield return null;
|
||||
Assert.IsTrue(prev.Equals(window._burstDisassembler),
|
||||
"Public fields changed in burstDisassembler even though they shouldn't");
|
||||
|
||||
prev = new BurstDisassemblerWithCopy(window._burstDisassembler);
|
||||
window.SendEvent(new Event() { type = EventType.MouseUp, mousePosition = Vector2.zero });
|
||||
yield return null;
|
||||
Assert.IsTrue(prev.Equals(window._burstDisassembler),
|
||||
"Public fields changed in burstDisassembler even though they shouldn't");
|
||||
|
||||
prev = new BurstDisassemblerWithCopy(window._burstDisassembler);
|
||||
yield return SelectJobAwaitLoad(jobName2);
|
||||
window = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
|
||||
window.SendEvent(new Event()
|
||||
{
|
||||
type = EventType.Repaint,
|
||||
mousePosition = new Vector2(window.position.width / 2f, window.position.height / 2f)
|
||||
});
|
||||
yield return null;
|
||||
Assert.IsFalse(prev.Equals(window._burstDisassembler), "Public fields of burstDisassembler did not change");
|
||||
}
|
||||
finally
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator InspectorStallingLoadTest()
|
||||
{
|
||||
// Error was triggered by selecting a display name, filtering it out, and then doing a script recompilation.
|
||||
yield return SelectJobAwaitLoad("BurstInspectorGUITests.MyJob - (IJob)");
|
||||
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
win._searchFieldJobs.SetFocus();
|
||||
yield return null;
|
||||
|
||||
// Simulate event for sending "a" as it will filter out the chosen job.
|
||||
win.SendEvent(Event.KeyboardEvent("a"));
|
||||
yield return null;
|
||||
|
||||
// Send RequestScriptReload to try and trigger the bug
|
||||
// and wait for it to return
|
||||
EditorUtility.RequestScriptReload();
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
// Wait for it to actually initialize.
|
||||
yield return _waitForInitialized;
|
||||
|
||||
Assert.IsTrue(win._initialized, "BurstInspector did not initialize properly after script reload");
|
||||
|
||||
win.Close();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator FontStyleDuringDomainReloadTest()
|
||||
{
|
||||
// Enter play mod
|
||||
yield return new EnterPlayMode();
|
||||
|
||||
// Exit play mode
|
||||
yield return new ExitPlayMode();
|
||||
|
||||
// Wait for the inspector to actually reload
|
||||
yield return _waitForInitialized;
|
||||
|
||||
var inspectorWindow = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
Assert.AreEqual("RobotoMono-Regular", inspectorWindow._font.name);
|
||||
#else
|
||||
if (Application.platform == RuntimePlatform.WindowsEditor)
|
||||
{
|
||||
Assert.AreEqual("Consolas", inspectorWindow._font.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual("Courier", inspectorWindow._font.name);
|
||||
}
|
||||
#endif
|
||||
|
||||
inspectorWindow.Close();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator BranchHoverTest()
|
||||
{
|
||||
const string jobName = "BurstInspectorGUITests.MyJob - (IJob)";
|
||||
|
||||
yield return SelectJobAwaitLoad(jobName);
|
||||
var info = SetupBranchTest();
|
||||
var window = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
window.SendEvent(new Event() { type = EventType.MouseUp, mousePosition = info.mousePos });
|
||||
var branch = window._textArea.hoveredBranch;
|
||||
yield return null;
|
||||
|
||||
// Close window to avoid it sending more events
|
||||
window.Close();
|
||||
|
||||
Assert.AreNotEqual(branch, default(LongTextArea.Branch), "Mouse is not hovering any branch.");
|
||||
Assert.AreEqual(info.blockIdx.src, branch.Edge.OriginRef.BlockIndex);
|
||||
Assert.AreEqual(info.blockIdx.dst, branch.Edge.LineRef.BlockIndex);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ClickBranchTest()
|
||||
{
|
||||
const string jobName = "BurstInspectorGUITests.MyJob - (IJob)";
|
||||
|
||||
yield return SelectJobAwaitLoad(jobName);
|
||||
var info = SetupBranchTest();
|
||||
|
||||
var window = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
|
||||
// Seeing if clicking the branch takes us to a spot where branch is still hovered.
|
||||
window.SendEvent(new Event() { type = EventType.MouseDown, mousePosition = info.mousePos });
|
||||
var branch = window._textArea.hoveredBranch;
|
||||
yield return null;
|
||||
|
||||
Assert.AreNotEqual(branch, default(LongTextArea.Branch), "Mouse is not hovering any branch.");
|
||||
Assert.AreEqual(info.blockIdx.src, branch.Edge.OriginRef.BlockIndex);
|
||||
Assert.AreEqual(info.blockIdx.dst, branch.Edge.LineRef.BlockIndex);
|
||||
|
||||
// Going back again.
|
||||
window.SendEvent(new Event() { type = EventType.MouseDown, mousePosition = info.mousePos });
|
||||
var branch2 = window._textArea.hoveredBranch;
|
||||
yield return null;
|
||||
|
||||
Assert.AreNotEqual(branch2, default(LongTextArea.Branch), "Mouse is not hovering any branch.");
|
||||
Assert.AreEqual(info.blockIdx.src, branch2.Edge.OriginRef.BlockIndex);
|
||||
Assert.AreEqual(info.blockIdx.dst, branch2.Edge.LineRef.BlockIndex);
|
||||
|
||||
// Close window to avoid it sending more events.
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private struct InfoThingy
|
||||
{
|
||||
public (int src, int dst) blockIdx;
|
||||
public Vector2 mousePos;
|
||||
}
|
||||
|
||||
private InfoThingy SetupBranchTest()
|
||||
{
|
||||
var window = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
// Make sure we use fontSize 12:
|
||||
window.fontSizeIndex = 4;
|
||||
window._textArea.Invalidate();
|
||||
window.fixedFontStyle = null;
|
||||
// Force window size to actually show branch arrows.
|
||||
window.position = new Rect(window.position.x, window.position.y, 390, 405);
|
||||
|
||||
// Sending event to set the displayname, to avoid it resetting _scrollPos because of target change.
|
||||
// Sending two events as initial guess for buttonbar width might be off, and it will be a precise calculation after second event.
|
||||
window.SendEvent(new Event() { type = EventType.Repaint, mousePosition = new Vector2(window.position.width / 2f, window.position.height / 2f) });
|
||||
window.SendEvent(new Event() { type = EventType.Repaint, mousePosition = new Vector2(window.position.width / 2f, window.position.height / 2f) });
|
||||
|
||||
// Setting up for the test.
|
||||
// Finding an edge:
|
||||
int dstBlockIdx = -1;
|
||||
int srcBlockIdx = -1;
|
||||
int line = -1;
|
||||
for (int idx = 0; idx < window._burstDisassembler.Blocks.Count; idx++)
|
||||
{
|
||||
var block = window._burstDisassembler.Blocks[idx];
|
||||
if (block.Edges != null)
|
||||
{
|
||||
foreach (var edge in block.Edges)
|
||||
{
|
||||
if (edge.Kind == BurstDisassembler.AsmEdgeKind.OutBound)
|
||||
{
|
||||
dstBlockIdx = edge.LineRef.BlockIndex;
|
||||
line = window._textArea.blockLine[dstBlockIdx];
|
||||
if ((dstBlockIdx == idx + 1 && edge.LineRef.LineIndex == 0)) // pointing to next line
|
||||
{
|
||||
continue;
|
||||
}
|
||||
srcBlockIdx = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (srcBlockIdx != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (srcBlockIdx == -1)
|
||||
{
|
||||
window.Close();
|
||||
throw new System.Exception("No edges present in assembly for \"BurstInspectorGUITests.MyJob - (IJob)\"");
|
||||
}
|
||||
|
||||
float dist = window._textArea.fontHeight * line;
|
||||
|
||||
float x = (window.position.width - (window._inspectorView.width + BurstInspectorGUI._scrollbarThickness)) + window._textArea.horizontalPad - (2*window._textArea.fontWidth);
|
||||
|
||||
// setting _ScrollPos so end of arrow is at bottom of screen, to make sure there is actually room for the scrolling.
|
||||
window._scrollPos = new Vector2(0, dist - window._inspectorView.height * 0.93f);
|
||||
|
||||
// Setting mousePos to bottom of inspector view.
|
||||
float topOfInspectorToBranchArrow = window._buttonOverlapInspectorView + 66.5f;//66.5f is the size of space over the treeview of different jobs.
|
||||
|
||||
var mousePos = new Vector2(x, topOfInspectorToBranchArrow + window._inspectorView.height - 0.5f*window._textArea.fontHeight);
|
||||
|
||||
return new InfoThingy() { blockIdx = (srcBlockIdx, dstBlockIdx), mousePos = mousePos};
|
||||
}
|
||||
|
||||
public static IEnumerable ValueSource
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return "BurstInspectorGUITests.MyJob - (IJob)";
|
||||
yield return "BurstReflectionTests.GenericType`1.NestedGeneric`1[System.Int32,System.Single].TestMethod3()";
|
||||
yield return "BurstReflectionTests.GenericType`1.NestedNonGeneric[System.Int32].TestMethod2()";
|
||||
yield return "BurstReflectionTests.GenericParallelForJob`1[System.Int32] - (IJobParallelFor)";
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator FocusCodeTest([ValueSource(nameof(ValueSource))] string job)
|
||||
{
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
yield return SelectJobAwaitLoad(job);
|
||||
|
||||
// Doesn't check that it's at the right spot, simply that it actually moves
|
||||
Assert.IsFalse(Mathf.Approximately(win._inspectorView.y, 0f), "Inspector view did not change");
|
||||
win.Close();
|
||||
}
|
||||
|
||||
public static IEnumerable FocusCodeNotBranchesSource
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return (1000, false);
|
||||
yield return (563, true);
|
||||
}
|
||||
}
|
||||
[UnityTest]
|
||||
public IEnumerator FocusCodeNotBranchesTest([ValueSource(nameof(FocusCodeNotBranchesSource))] (int, bool) input)
|
||||
{
|
||||
var (width, doFocus) = input;
|
||||
const string case1 = "BurstInspectorGUITests.BranchArrows - (IJob)";
|
||||
const string case2 = "BurstInspectorGUITests.BranchArrows2 - (IJob)";
|
||||
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
// Force window size to be small enough for it to position it more to the right.
|
||||
win.position = new Rect(win.position.x, win.position.y, width, 405);
|
||||
|
||||
// Test one where it should focus.
|
||||
yield return SelectJobAwaitLoad(case1);
|
||||
|
||||
var val1 = win._inspectorView.x;
|
||||
var result1 = Mathf.Approximately(val1, 0f);
|
||||
|
||||
|
||||
// Test two with no focus.
|
||||
win._assemblyKind = BurstInspectorGUI.AssemblyOptions.PlainWithDebugInformation;
|
||||
yield return SelectJobAwaitLoad(case2);
|
||||
|
||||
var val2 = win._inspectorView.x;
|
||||
var result2 = Mathf.Approximately(val2, 0f);
|
||||
|
||||
// Cleanup and test assertions.
|
||||
win.Close();
|
||||
Assert.AreEqual(doFocus, result1 == doFocus, $"Inspector view wrong.");
|
||||
//Assert.IsFalse(result1, $"Inspector view did not change (Is {val1}).");
|
||||
Assert.IsTrue(result2, $"Inspector view changed unexpectedly (Is {val2}).");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SelectionNotOutsideBoundsTest()
|
||||
{
|
||||
void MoveSelection(BurstInspectorGUI gui, LongTextArea.Direction dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case LongTextArea.Direction.Down:
|
||||
gui._textArea.SelectAll();
|
||||
gui._textArea.MoveSelectionDown(gui._inspectorView, true);
|
||||
break;
|
||||
case LongTextArea.Direction.Right:
|
||||
gui._textArea.SelectAll();
|
||||
gui._textArea.MoveSelectionRight(gui._inspectorView, true);
|
||||
break;
|
||||
case LongTextArea.Direction.Left:
|
||||
gui._textArea.selectDragPos = Vector2.zero;
|
||||
gui._textArea.MoveSelectionLeft(gui._inspectorView, true);
|
||||
break;
|
||||
case LongTextArea.Direction.Up:
|
||||
gui._textArea.selectDragPos = Vector2.zero;
|
||||
gui._textArea.MoveSelectionUp(gui._inspectorView, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
yield return SelectJobAwaitLoad("BurstInspectorGUITests.MyJob - (IJob)");
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var dir in Enum.GetValues(typeof(LongTextArea.Direction)))
|
||||
{
|
||||
MoveSelection(win, (LongTextArea.Direction)dir);
|
||||
yield return null;
|
||||
|
||||
// Check that no errors have happened.
|
||||
LogAssert.NoUnexpectedReceived();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
win.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SelectionInAssemblySearchBarTest()
|
||||
{
|
||||
yield return SelectJobAwaitLoad("BurstInspectorGUITests.MyJob - (IJob)");
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
win._searchFieldAssembly.SetFocus();
|
||||
yield return null;
|
||||
|
||||
// Send events to input some text.
|
||||
win.SendEvent(Event.KeyboardEvent("a"));
|
||||
win.SendEvent(Event.KeyboardEvent("b"));
|
||||
|
||||
yield return null;
|
||||
|
||||
// Move select some using keyboard input
|
||||
win.SendEvent(Event.KeyboardEvent("left"));
|
||||
win.SendEvent(Event.KeyboardEvent("#right"));
|
||||
|
||||
yield return null;
|
||||
|
||||
// Do a copy
|
||||
var savedClipBoard = EditorGUIUtility.systemCopyBuffer;
|
||||
win.SendEvent(SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX
|
||||
? Event.KeyboardEvent("%c")
|
||||
: Event.KeyboardEvent("^c"));
|
||||
yield return null;
|
||||
|
||||
var copiedText = EditorGUIUtility.systemCopyBuffer;
|
||||
EditorGUIUtility.systemCopyBuffer = savedClipBoard;
|
||||
|
||||
// Check that all is good
|
||||
win.Close();
|
||||
|
||||
Assert.AreEqual("b", copiedText, "Copied text did not match expectation.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GoToNextSearchTargetTest()
|
||||
{
|
||||
var active = -1;
|
||||
var nextActive = -1;
|
||||
|
||||
yield return SelectJobAwaitLoad("BurstInspectorGUITests.MyJob - (IJob)");
|
||||
var win = EditorWindow.GetWindow<BurstInspectorGUI>();
|
||||
|
||||
try
|
||||
{
|
||||
win._searchFieldAssembly.SetFocus();
|
||||
yield return null;
|
||||
|
||||
// Do a search in the text.
|
||||
win.SendEvent(Event.KeyboardEvent("p"));
|
||||
win.SendEvent(Event.KeyboardEvent("u"));
|
||||
win.SendEvent(Event.KeyboardEvent("return"));
|
||||
yield return null;
|
||||
|
||||
active = win._textArea._activeSearchHitIdx;
|
||||
|
||||
// Select next search target.
|
||||
win.SendEvent(Event.KeyboardEvent("return"));
|
||||
yield return null;
|
||||
|
||||
nextActive = win._textArea._activeSearchHitIdx;
|
||||
}
|
||||
finally
|
||||
{
|
||||
win.Close();
|
||||
}
|
||||
|
||||
Assert.AreNotEqual(active, nextActive, "Active search target was not changed.");
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct MyJob : IJob
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<float> Inpút;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<float> Output;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
float result = 0.0f;
|
||||
for (int i = 0; i < Inpút.Length; i++)
|
||||
{
|
||||
result += Inpút[i];
|
||||
}
|
||||
Output[0] = result;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct BranchArrows : IJob
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<float> Inpút;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<float> Output;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
float result = 0.0f;
|
||||
for (int i = 0; i < Inpút.Length; i++)
|
||||
{
|
||||
if (Inpút[i] < 10) { result += 1; }
|
||||
else if (Inpút[i] < 20) { result += 2; }
|
||||
else if (Inpút[i] < 30) { result += 3; }
|
||||
else if (Inpút[i] < 40) { result += 4; }
|
||||
else if (Inpút[i] < 50) { result += 5; }
|
||||
else if (Inpút[i] < 60) { result += 6; }
|
||||
else if (Inpút[i] < 70) { result += 7; }
|
||||
else if (Inpút[i] < 80) { result += 8; }
|
||||
else if (Inpút[i] < 90) { result += 9; }
|
||||
result += Inpút[i];
|
||||
}
|
||||
Output[0] = result;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct BranchArrows2 : IJob
|
||||
{
|
||||
[ReadOnly]
|
||||
public NativeArray<float> Inpút;
|
||||
|
||||
[WriteOnly]
|
||||
public NativeArray<float> Output;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
float result = 0.0f;
|
||||
for (int i = 0; i < Inpút.Length; i++)
|
||||
{
|
||||
if (Inpút[i] < 10) { result += 1; }
|
||||
else if (Inpút[i] < 20) { result += 2; }
|
||||
else if (Inpút[i] < 30) { result += 3; }
|
||||
else if (Inpút[i] < 40) { result += 4; }
|
||||
else if (Inpút[i] < 50) { result += 5; }
|
||||
else if (Inpút[i] < 60) { result += 6; }
|
||||
else if (Inpút[i] < 70) { result += 7; }
|
||||
else if (Inpút[i] < 80) { result += 8; }
|
||||
else if (Inpút[i] < 90) { result += 9; }
|
||||
result += Inpút[i];
|
||||
}
|
||||
Output[0] = result;
|
||||
}
|
||||
}
|
||||
|
||||
private class BurstDisassemblerWithCopy : BurstDisassembler
|
||||
{
|
||||
public List<AsmBlock> BlocksCopy;
|
||||
public bool IsColoredCopy;
|
||||
public List<AsmLine> LinesCopy;
|
||||
public List<AsmToken> TokensCopy;
|
||||
public BurstDisassemblerWithCopy(BurstDisassembler disassembler) : base()
|
||||
{
|
||||
IsColoredCopy = disassembler.IsColored;
|
||||
|
||||
BlocksCopy = new List<AsmBlock>(disassembler.Blocks);
|
||||
LinesCopy = new List<AsmLine>(disassembler.Lines);
|
||||
TokensCopy = new List<AsmToken>(disassembler.Tokens);
|
||||
}
|
||||
|
||||
public bool Equals(BurstDisassembler other)
|
||||
{
|
||||
return IsColoredCopy == other.IsColored
|
||||
&& BlocksCopy.SequenceEqual(other.Blocks)
|
||||
&& LinesCopy.SequenceEqual(other.Lines)
|
||||
&& TokensCopy.SequenceEqual(other.Tokens);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5c2988be6da139988b149bb3b60dc9ca
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
using NUnit.Framework;
|
||||
using Unity.Burst.Editor;
|
||||
|
||||
public class BurstMathTests
|
||||
{
|
||||
[Test]
|
||||
[TestCase(1f, 3f, 3f, true)]
|
||||
[TestCase(1f, 3f, 2f, true)]
|
||||
[TestCase(1f, 3f, 3.00001f, false)]
|
||||
public void WithinRangeTest(float start, float end, float num, bool res)
|
||||
{
|
||||
Assert.That(BurstMath.WithinRange(start, end, num), Is.EqualTo(res));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6a647d1cecc83c4eaf9750af7ae6a1d0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,280 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using Unity.Burst.Editor;
|
||||
using Unity.Burst;
|
||||
using Unity.Jobs;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
public class BurstMethodTreeViewTests
|
||||
{
|
||||
/*
|
||||
Consists of a tree looking like:
|
||||
Root
|
||||
│
|
||||
└►BurstMethodTreeViewTests
|
||||
│
|
||||
│►Job1
|
||||
│ │
|
||||
│ └►TestMethod1
|
||||
│
|
||||
│►Job2
|
||||
│ │
|
||||
│ └►TestMethod1
|
||||
│
|
||||
│►Job3
|
||||
│ │
|
||||
│ └►TestMethod1(System.IntPtr)
|
||||
│
|
||||
│►Job4
|
||||
│ │
|
||||
│ └►TestMethod1
|
||||
│
|
||||
└►Job5 - (IJob)
|
||||
*/
|
||||
private BurstMethodTreeView _treeView;
|
||||
|
||||
private List<BurstCompileTarget> _targets;
|
||||
|
||||
private string _filter;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_filter = string.Empty;
|
||||
|
||||
_treeView = new BurstMethodTreeView(
|
||||
new TreeViewState(),
|
||||
() => _filter,
|
||||
() => (true, true)
|
||||
);
|
||||
|
||||
string name = "TestMethod1";
|
||||
_targets = new List<BurstCompileTarget>
|
||||
{
|
||||
new BurstCompileTarget(typeof(Job1).GetMethod(name), typeof(Job1), null, true),
|
||||
new BurstCompileTarget(typeof(Job2).GetMethod(name), typeof(Job2), null, true),
|
||||
new BurstCompileTarget(typeof(Job3).GetMethod(name), typeof(Job3), null, true),
|
||||
new BurstCompileTarget(typeof(Job4).GetMethod(name), typeof(Job4), null, true),
|
||||
new BurstCompileTarget(typeof(Job5).GetMethod("Execute"), typeof(Job5), typeof(IJob), false),
|
||||
};
|
||||
}
|
||||
|
||||
private void testEquality<T>(List<T> exp, List<T> act)
|
||||
{
|
||||
Assert.AreEqual(exp.Count, act.Count, "List length did not match.");
|
||||
|
||||
if (exp is List<TreeViewItem> elist && act is List<TreeViewItem> alist)
|
||||
{
|
||||
for (int i = 0; i < act.Count; i++)
|
||||
{
|
||||
Assert.IsTrue(alist[i].CompareTo(elist[i]) == 0,
|
||||
$"expected: {elist[i].displayName}\nactual: {alist[i].displayName}");
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < act.Count; i++)
|
||||
{
|
||||
Assert.AreEqual(exp[i], act[i], $"list items did not match at index {i}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProcessNewItemTest()
|
||||
{
|
||||
// Test for method containing . in name:
|
||||
List<StringSlice> oldNameSpace = new List<StringSlice>();
|
||||
int idJ = 0;
|
||||
var (idn, newtarget, nameSpace) =
|
||||
BurstMethodTreeView.ProcessNewItem(0, ++idJ, _targets[2], oldNameSpace);
|
||||
|
||||
Assert.AreEqual(-2, idn);
|
||||
var expTargets = new List<TreeViewItem>
|
||||
{
|
||||
new TreeViewItem(-1, 0, $"{nameof(BurstMethodTreeViewTests)}"),
|
||||
new TreeViewItem(-2,1,$"{nameof(Job3)}"),
|
||||
new TreeViewItem(1, 2, "TestMethod1(System.IntPtr)")
|
||||
};
|
||||
var expNS = new List<StringSlice>
|
||||
{
|
||||
new StringSlice($"{nameof(BurstMethodTreeViewTests)}"),
|
||||
new StringSlice($"{nameof(Job3)}")
|
||||
};
|
||||
testEquality(expTargets, newtarget);
|
||||
testEquality(expNS, nameSpace);
|
||||
|
||||
// Test for method with . and with thing in namespace:
|
||||
(idn, newtarget, nameSpace) = BurstMethodTreeView.ProcessNewItem(idn, ++idJ, _targets[2], nameSpace);
|
||||
Assert.AreEqual(-2, idn); // no new non-leafs added.
|
||||
expTargets = new List<TreeViewItem>
|
||||
{
|
||||
new TreeViewItem(2, 2, "TestMethod1(System.IntPtr)")
|
||||
};
|
||||
testEquality(expTargets, newtarget);
|
||||
testEquality(expNS, nameSpace);
|
||||
|
||||
// Test with IJob instead of static method:
|
||||
(idn, newtarget, nameSpace) = BurstMethodTreeView.ProcessNewItem(0, ++idJ, _targets[4], oldNameSpace);
|
||||
Assert.AreEqual(-1, idn); // no new non-leafs added.
|
||||
expTargets = new List<TreeViewItem>
|
||||
{
|
||||
new TreeViewItem(-1, 0, $"{nameof(BurstMethodTreeViewTests)}"),
|
||||
new TreeViewItem(2, 2, $"{nameof(Job5)} - ({nameof(IJob)})")
|
||||
};
|
||||
expNS = new List<StringSlice> { new StringSlice($"{nameof(BurstMethodTreeViewTests)}"), };
|
||||
testEquality(expTargets, newtarget);
|
||||
testEquality(expNS, nameSpace);
|
||||
}
|
||||
|
||||
|
||||
private readonly (string, string[])[] _findNameSpacesTestInput =
|
||||
{
|
||||
("Burst.Compiler.IL.Tests.TestGenerics+GenericStructOuter2`2+GenericStructInner`1[[Burst.Compiler.IL.Tests.TestGenerics+MyValueData1, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[Burst.Compiler.IL.Tests.TestGenerics+MyValueData2, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[Burst.Compiler.IL.Tests.TestGenerics+MyValueData2, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]",
|
||||
new []{ "Burst.Compiler.IL.Tests.TestGenerics", "GenericStructOuter2`2" })
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void ExtractNameSpacesTest()
|
||||
{
|
||||
foreach (var (displayName, expectedNameSpaces) in _findNameSpacesTestInput)
|
||||
{
|
||||
var (nameSpaces, methodNameIdx) = BurstMethodTreeView.ExtractNameSpaces(displayName);
|
||||
|
||||
Assert.AreEqual(2, nameSpaces.Count, "Amount of namespaces found is wrong.");
|
||||
int len = expectedNameSpaces.Length;
|
||||
int expectedNSIdx = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
expectedNSIdx += expectedNameSpaces[i].Length + 1;
|
||||
Assert.AreEqual(expectedNameSpaces[i], nameSpaces[i].ToString(), "Wrong namespace name retrieval.");
|
||||
}
|
||||
Assert.AreEqual(expectedNSIdx, methodNameIdx, "Wrong index of method name.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void InitializeTest()
|
||||
{
|
||||
const int numNodes = 1 + 5; // Root + internal nodes.
|
||||
_treeView.Initialize(_targets, false);
|
||||
Assert.AreEqual(numNodes, _treeView.GetExpanded().Count, "All menu items should be expanded");
|
||||
|
||||
_treeView.SetExpanded(-2, false);
|
||||
Assert.AreEqual(numNodes-1, _treeView.GetExpanded().Count, "First Job should be folded.");
|
||||
|
||||
_treeView.Initialize(_targets, true);
|
||||
Assert.AreEqual(numNodes-1, _treeView.GetExpanded().Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildRootTest()
|
||||
{
|
||||
_treeView.Initialize(_targets, false);
|
||||
|
||||
int dexp = 0;
|
||||
int idNexp = -1;
|
||||
int idLexp = 1;
|
||||
foreach (TreeViewItem twi in _treeView.GetRows())
|
||||
{
|
||||
Assert.AreEqual(dexp++, twi.depth, $"Depth of item \"{twi}\" was wrong.");
|
||||
if (dexp > 2) { dexp = 1; }
|
||||
|
||||
Assert.AreEqual(twi.hasChildren ? idNexp-- : idLexp++, twi.id, $"ID of item \"{twi}\" was wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSelection()
|
||||
{
|
||||
_treeView.Initialize(_targets, false);
|
||||
|
||||
IList<int> actual = _treeView.GetSelection();
|
||||
Assert.IsEmpty(actual, "Selection count wrong.");
|
||||
|
||||
_treeView.SelectAllRows();
|
||||
actual = _treeView.GetSelection();
|
||||
Assert.IsEmpty(actual, "Selection count wrong. Multirow selection not allowed.");
|
||||
|
||||
_treeView.SetSelection(new List<int> { -2 });
|
||||
actual = _treeView.GetSelection();
|
||||
Assert.AreEqual(0, actual.Count, "Selection count wrong. Label selection not allowed.");
|
||||
|
||||
_treeView.SetSelection(new List<int> { 1 });
|
||||
actual = _treeView.GetSelection();
|
||||
Assert.AreEqual(1, actual.Count, "Selection count wrong.");
|
||||
Assert.AreEqual(1, actual[0], "Selection ID wrong.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TrySelectByDisplayNameTest()
|
||||
{
|
||||
const string name = "BurstMethodTreeViewTests.Job1.TestMethod1()";
|
||||
_treeView.Initialize(_targets, false);
|
||||
|
||||
Assert.IsFalse(_treeView.TrySelectByDisplayName("Not present"));
|
||||
|
||||
Assert.IsTrue(_treeView.TrySelectByDisplayName(name), "TreeView Could not find method.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ProcessEntireTestProject()
|
||||
{
|
||||
// Make it filter out some jobs:
|
||||
_filter = "Unity";
|
||||
|
||||
// Get all target jobs!
|
||||
var assemblyList = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs;
|
||||
var result = BurstReflection.FindExecuteMethods(assemblyList, BurstReflectionAssemblyOptions.None).CompileTargets;
|
||||
result.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal));
|
||||
|
||||
// Initialize the tree view:
|
||||
_treeView.Initialize(result, false);
|
||||
|
||||
// Check if everything is good and ready:
|
||||
var visibleJobs = _treeView.GetRows().Where(twi => !twi.hasChildren);
|
||||
foreach (TreeViewItem twi in visibleJobs)
|
||||
{
|
||||
var actual = result[twi.id - 1];
|
||||
var expected = twi.displayName;
|
||||
|
||||
Assert.IsTrue(actual.GetDisplayName().Contains(expected), $"Retrieved the wrong target base on id.\nGot \"{actual.GetDisplayName()}\"\nExpected \"{expected}\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[BurstCompile]
|
||||
private struct Job1
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod1() { }
|
||||
}
|
||||
[BurstCompile]
|
||||
private struct Job2
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod1() { }
|
||||
}
|
||||
[BurstCompile]
|
||||
private struct Job3
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod1(System.IntPtr ptr) { }
|
||||
}
|
||||
[BurstCompile]
|
||||
private struct Job4
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod1() { }
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct Job5 : IJob
|
||||
{
|
||||
public void Execute() { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dec061e3cbd730ce8117c465ee02452c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,197 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Burst;
|
||||
using Unity.Burst.Editor;
|
||||
using Unity.Jobs;
|
||||
|
||||
// This concrete generic type is only referenced in this assembly-level attribute,
|
||||
// not anywhere else in code. This is to test that such types can be picked up
|
||||
// by BurstReflection.
|
||||
[assembly: BurstReflectionTests.RegisterGenericJobType(typeof(BurstReflectionTests.GenericParallelForJob<int>))]
|
||||
|
||||
[TestFixture]
|
||||
public class BurstReflectionTests
|
||||
{
|
||||
private List<System.Reflection.Assembly> _assemblies;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_assemblies = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetAssemblyList()
|
||||
{
|
||||
Assert.That(_assemblies, Has.Count.GreaterThan(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("BurstReflectionTests.MyJob - (IJob)")]
|
||||
[TestCase("BurstReflectionTests.MyGenericJob`1[System.Int32] - (IJob)")]
|
||||
[TestCase("BurstReflectionTests.MyGenericJob2`1[System.Int32] - (BurstReflectionTests.IMyGenericJob`1[System.Int32])")]
|
||||
[TestCase("BurstReflectionTests.MyGenericJob2`1[System.Double] - (BurstReflectionTests.IMyGenericJob`1[System.Double])")]
|
||||
[TestCase("BurstReflectionTests.NonGenericType.TestMethod1()")]
|
||||
[TestCase("BurstReflectionTests.GenericType`1[System.Int32].TestMethod1()")]
|
||||
[TestCase("BurstReflectionTests.GenericType`1.NestedNonGeneric[System.Int32].TestMethod2()")]
|
||||
[TestCase("BurstReflectionTests.GenericType`1.NestedGeneric`1[System.Int32,System.Single].TestMethod3()")]
|
||||
[TestCase("BurstReflectionTests.MyGenericJobSeparateAssembly`1[System.Int32] - (BurstReflectionTestsSeparateAssembly.IMyGenericJobSeparateAssembly`1[System.Int32])")]
|
||||
[TestCase("BurstReflectionTests.GenericParallelForJob`1[System.Int32] - (IJobParallelFor)")]
|
||||
public void CanFindJobType(string compileTargetName)
|
||||
{
|
||||
var result = BurstReflection.FindExecuteMethods(_assemblies, BurstReflectionAssemblyOptions.None);
|
||||
|
||||
Assert.That(result.LogMessages, Is.Empty);
|
||||
|
||||
var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName);
|
||||
Assert.That(compileTarget, Is.Not.Null);
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct MyJob : IJob
|
||||
{
|
||||
public void Execute() { }
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct MyGenericJob<T> : IJob
|
||||
{
|
||||
public void Execute() { }
|
||||
|
||||
private static void UseConcreteType()
|
||||
{
|
||||
new MyGenericJob<int>().Execute();
|
||||
}
|
||||
}
|
||||
|
||||
[Unity.Jobs.LowLevel.Unsafe.JobProducerType(typeof(MyJobProducer<,>))]
|
||||
private interface IMyGenericJob<T>
|
||||
{
|
||||
void Execute();
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct MyGenericJob2<T> : IMyGenericJob<T>
|
||||
{
|
||||
public void Execute() { }
|
||||
|
||||
private static void UseConcreteType()
|
||||
{
|
||||
new MyGenericJob2<int>().Execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyJobProducer<TJob, T>
|
||||
{
|
||||
public static void Execute(ref TJob job)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private struct MyGenericJob2Wrapper<T1, T2>
|
||||
{
|
||||
public MyGenericJob2<T2> Job;
|
||||
|
||||
private static void UseConcreteType()
|
||||
{
|
||||
var x = new MyGenericJob2Wrapper<float, double>();
|
||||
x.Job.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct NonGenericType
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod1() { }
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct GenericType<T>
|
||||
{
|
||||
public static Action Delegate1;
|
||||
public static Action Delegate2;
|
||||
public static Action Delegate3;
|
||||
|
||||
[BurstCompile]
|
||||
public static void TestMethod1() { }
|
||||
|
||||
[BurstCompile]
|
||||
public class NestedNonGeneric
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod2() { }
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
public class NestedGeneric<T2>
|
||||
{
|
||||
[BurstCompile]
|
||||
public static void TestMethod3() { }
|
||||
}
|
||||
|
||||
private static void UseConcreteType()
|
||||
{
|
||||
// Store the delegates to static fields to avoid
|
||||
// them being optimized-away in Release builds
|
||||
Delegate1 = GenericType<int>.TestMethod1;
|
||||
Delegate2 = GenericType<int>.NestedNonGeneric.TestMethod2;
|
||||
Delegate3 = GenericType<int>.NestedGeneric<float>.TestMethod3;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private struct MyGenericJobSeparateAssembly<T> : BurstReflectionTestsSeparateAssembly.IMyGenericJobSeparateAssembly<T>
|
||||
{
|
||||
public void Execute() { }
|
||||
|
||||
private static void UseConcreteType()
|
||||
{
|
||||
new MyGenericJobSeparateAssembly<int>().Execute();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("BurstReflectionTests.GenericMethodContainer.GenericMethod(T)")]
|
||||
public void ExcludesGenericMethods(string compileTargetName)
|
||||
{
|
||||
var result = BurstReflection.FindExecuteMethods(_assemblies, BurstReflectionAssemblyOptions.None);
|
||||
|
||||
Assert.That(result.LogMessages, Is.Empty);
|
||||
|
||||
var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName);
|
||||
Assert.That(compileTarget, Is.Null);
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private static class GenericMethodContainer
|
||||
{
|
||||
[BurstCompile]
|
||||
private static void GenericMethod<T>(T p)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
internal class RegisterGenericJobTypeAttribute : Attribute
|
||||
{
|
||||
public Type ConcreteType;
|
||||
|
||||
public RegisterGenericJobTypeAttribute(Type type)
|
||||
{
|
||||
ConcreteType = type;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
internal struct GenericParallelForJob<T> : IJobParallelFor
|
||||
where T : struct
|
||||
{
|
||||
public void Execute(int index)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fde1edfe51dc3deaa53f0952dddf2b02
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,131 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using NUnit.Framework;
|
||||
using Unity.Burst;
|
||||
using Unity.Burst.Editor;
|
||||
|
||||
public class BurstStringSearchTests
|
||||
{
|
||||
private BurstDisassembler GetDisassemblerandText(string compileTargetName, int debugLvl, out string textToRender)
|
||||
{
|
||||
// Get target job assembly:
|
||||
var assemblies = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs;
|
||||
var result = BurstReflection.FindExecuteMethods(assemblies, BurstReflectionAssemblyOptions.None);
|
||||
var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName);
|
||||
|
||||
Assert.IsTrue(compileTarget != default, $"Could not find compile target: {compileTarget}");
|
||||
|
||||
BurstDisassembler disassembler = new BurstDisassembler();
|
||||
|
||||
var options = new StringBuilder();
|
||||
|
||||
compileTarget.Options.TryGetOptions(compileTarget.JobType, true, out string defaultOptions);
|
||||
options.AppendLine(defaultOptions);
|
||||
// Disables the 2 current warnings generated from code (since they clutter up the inspector display)
|
||||
// BC1370 - throw inside code not guarded with ConditionalSafetyCheck attribute
|
||||
// BC1322 - loop intrinsic on loop that has been optimised away
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDisableWarnings, "BC1370;BC1322")}");
|
||||
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, BurstTargetCpu.X64_SSE4)}");
|
||||
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDebug, $"{debugLvl}")}");
|
||||
|
||||
var baseOptions = options.ToString();
|
||||
|
||||
var append = BurstInspectorGUI.GetDisasmOptions()[(int)DisassemblyKind.Asm];
|
||||
|
||||
// Setup disAssembler with the job:
|
||||
compileTarget.RawDisassembly = BurstInspectorGUI.GetDisassembly(compileTarget.Method, baseOptions + append);
|
||||
textToRender = compileTarget.RawDisassembly.TrimStart('\n');
|
||||
|
||||
return disassembler;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindLineNrTest()
|
||||
{
|
||||
// Load in a test text
|
||||
var disassembler = GetDisassemblerandText("BurstInspectorGUITests.MyJob - (IJob)", 1, out string textToRender);
|
||||
disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel, true, true);
|
||||
|
||||
var text = disassembler.GetOrRenderBlockToText(0);
|
||||
|
||||
// Call find line nr for:
|
||||
// first line
|
||||
// Around middle
|
||||
// Last line
|
||||
Assert.AreEqual(0, BurstStringSearch.FindLineNr(text, text.IndexOf('\n') - 1), "Couldn't find line 0");
|
||||
|
||||
Assert.AreEqual(2, BurstStringSearch.FindLineNr(text, text.IndexOf('\n', text.IndexOf('\n') + 1) + 1), "Couldn't find line in middle");
|
||||
|
||||
Assert.AreEqual(disassembler.Blocks[0].Length-1, BurstStringSearch.FindLineNr(text, text.Length-1), "Couldn't find last line");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetEndIndexOfPlainLineTest()
|
||||
{
|
||||
Assert.AreEqual(("This\nIs\nPerfect".Length-1, 6),
|
||||
BurstStringSearch.GetEndIndexOfPlainLine("This\nIs\nPerfect", 2),
|
||||
"Failed finding in well formed string");
|
||||
|
||||
const string text1 = "No line endings";
|
||||
Assert.AreEqual((text1.Length-1, text1.Length-1),
|
||||
BurstStringSearch.GetEndIndexOfPlainLine(text1, 0),
|
||||
"Failed for missing line ending");
|
||||
|
||||
const string text2 = "No Line endings too many lines";
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => BurstStringSearch.GetEndIndexOfPlainLine(text2, 2),
|
||||
"Failed for missing line ending and too high line number");
|
||||
|
||||
const string text3 = "Line ending\n";
|
||||
Assert.AreEqual((text3.Length-1, text3.Length-1),
|
||||
BurstStringSearch.GetEndIndexOfPlainLine(text3, 0),
|
||||
"Failed with line ending");
|
||||
|
||||
const string text4 = "Line ending too many lines\n";
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => BurstStringSearch.GetEndIndexOfPlainLine(text4, 2),
|
||||
"Failed with line endings and too high line number");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindMatchTest()
|
||||
{
|
||||
_ = GetDisassemblerandText("BurstInspectorGUITests.MyJob - (IJob)", 2, out var textToRender);
|
||||
|
||||
var expectedNormal = textToRender.IndexOf("def");
|
||||
var tmp = Regex.Match(textToRender, @"\bdef\b");
|
||||
var expectedWhole = tmp.Success ? tmp.Index : -1;
|
||||
|
||||
|
||||
// Normal search
|
||||
Assert.AreEqual((expectedNormal, 3),
|
||||
BurstStringSearch.FindMatch(textToRender,
|
||||
new SearchCriteria("def", false, false, false), default),
|
||||
"Standard search failed"); // standard search: Match def in .endef
|
||||
Assert.AreEqual((expectedWhole, 3),
|
||||
BurstStringSearch.FindMatch(textToRender,
|
||||
new SearchCriteria("def", false, true, false), default),
|
||||
"Standard whole words failed"); // whole word search: Match def in .def
|
||||
|
||||
// Regex search
|
||||
const RegexOptions opt = RegexOptions.CultureInvariant;
|
||||
Assert.AreEqual((expectedNormal, 3),
|
||||
BurstStringSearch.FindMatch(textToRender,
|
||||
new SearchCriteria("def", false, false, true),
|
||||
new Regex("def", opt | RegexOptions.IgnoreCase)),
|
||||
"Regex search failed"); // standard search: Match def in .endef
|
||||
Assert.AreEqual((expectedWhole, tmp.Success ? 3 : 0),
|
||||
BurstStringSearch.FindMatch(textToRender,
|
||||
new SearchCriteria(@"\bdef\b", false, true, true),
|
||||
new Regex(@"\bdef\b", opt)),
|
||||
"Regex whole word failed"); // whole word search: Match def in .def
|
||||
|
||||
// Across lines and blocks
|
||||
Assert.AreEqual((12, 4),
|
||||
BurstStringSearch.FindMatch(textToRender,
|
||||
new SearchCriteria(@"t[\n]+..", false, false, true),
|
||||
new Regex(@"t[\n]+..", opt | RegexOptions.IgnoreCase)),
|
||||
"Regex across lines failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2d306d2ea7783099abe61e86c377ca92
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,712 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using Unity.Jobs.LowLevel.Unsafe;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using UnityEditor;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using System.Text.RegularExpressions;
|
||||
using Unity.Profiling;
|
||||
using UnityEditor.Compilation;
|
||||
using System.IO;
|
||||
|
||||
[TestFixture]
|
||||
public class EditModeTest
|
||||
{
|
||||
private const int MaxIterations = 500;
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckBurstJobEnabledDisabled()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompileSynchronously = true;
|
||||
try
|
||||
{
|
||||
foreach(var item in CheckBurstJobDisabled()) yield return item;
|
||||
foreach(var item in CheckBurstJobEnabled()) yield return item;
|
||||
}
|
||||
finally
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompilation = true;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable CheckBurstJobEnabled()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompilation = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
using (var jobTester = new BurstJobTester2())
|
||||
{
|
||||
var result = jobTester.Calculate();
|
||||
Assert.AreNotEqual(0.0f, result);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable CheckBurstJobDisabled()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompilation = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
using (var jobTester = new BurstJobTester2())
|
||||
{
|
||||
var result = jobTester.Calculate();
|
||||
Assert.AreEqual(0.0f, result);
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckJobWithNativeArray()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompileSynchronously = true;
|
||||
BurstCompiler.Options.EnableBurstCompilation = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new BurstJobTester2.MyJobCreatingAndDisposingNativeArray()
|
||||
{
|
||||
Length = 128,
|
||||
Result = new NativeArray<int>(16, Allocator.TempJob)
|
||||
};
|
||||
var handle = job.Schedule();
|
||||
handle.Complete();
|
||||
try
|
||||
{
|
||||
Assert.AreEqual(job.Length, job.Result[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.Result.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_BURST_BUG_FUNCTION_POINTER_FIXED
|
||||
[UnityTest]
|
||||
public IEnumerator CheckBurstFunctionPointerException()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstCompileSynchronously = true;
|
||||
BurstCompiler.Options.EnableBurstCompilation = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
using (var jobTester = new BurstJobTester())
|
||||
{
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => jobTester.CheckFunctionPointer());
|
||||
StringAssert.Contains("Exception was thrown from a function compiled with Burst", exception.Message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
private struct HashTestJob : IJob
|
||||
{
|
||||
public NativeArray<int> Hashes;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
Hashes[0] = BurstRuntime.GetHashCode32<int>();
|
||||
Hashes[1] = TypeHashWrapper.GetIntHash();
|
||||
|
||||
Hashes[2] = BurstRuntime.GetHashCode32<TypeHashWrapper.SomeStruct<int>>();
|
||||
Hashes[3] = TypeHashWrapper.GetGenericHash<int>();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestTypeHash()
|
||||
{
|
||||
HashTestJob job = new HashTestJob
|
||||
{
|
||||
Hashes = new NativeArray<int>(4, Allocator.TempJob)
|
||||
};
|
||||
job.Schedule().Complete();
|
||||
|
||||
var hash0 = job.Hashes[0];
|
||||
var hash1 = job.Hashes[1];
|
||||
|
||||
var hash2 = job.Hashes[2];
|
||||
var hash3 = job.Hashes[3];
|
||||
|
||||
job.Hashes.Dispose();
|
||||
|
||||
Assert.AreEqual(hash0, hash1, "BurstRuntime.GetHashCode32<int>() has returned two different hashes");
|
||||
Assert.AreEqual(hash2, hash3, "BurstRuntime.GetHashCode32<SomeStruct<int>>() has returned two different hashes");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksWithDomainReload()
|
||||
{
|
||||
{
|
||||
var job = new SafetyCheckJobWithDomainReload();
|
||||
{
|
||||
// Run with safety-checks true
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
job.Result = new NativeArray<int>(1, Allocator.TempJob);
|
||||
try
|
||||
{
|
||||
var handle = job.Schedule();
|
||||
handle.Complete();
|
||||
Assert.AreEqual(2, job.Result[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.Result.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Run with safety-checks false
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = false;
|
||||
job.Result = new NativeArray<int>(1, Allocator.TempJob);
|
||||
bool hasException = false;
|
||||
try
|
||||
{
|
||||
var handle = job.Schedule();
|
||||
handle.Complete();
|
||||
Assert.AreEqual(1, job.Result[0]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
hasException = true;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.Result.Dispose();
|
||||
if (hasException)
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for domain reload
|
||||
EditorUtility.RequestScriptReload();
|
||||
|
||||
// Wait for the domain reload to be completed
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
{
|
||||
// The safety checks should have been disabled by the previous code
|
||||
Assert.False(BurstCompiler.Options.EnableBurstSafetyChecks);
|
||||
// Restore safety checks
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
private struct DebugLogJob : IJob
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
UnityEngine.Debug.Log($"This is a string logged from a job with burst with the following {Value}");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestDebugLog()
|
||||
{
|
||||
var job = new DebugLogJob
|
||||
{
|
||||
Value = 256
|
||||
};
|
||||
job.Schedule().Complete();
|
||||
}
|
||||
|
||||
[BurstCompile(CompileSynchronously = true, Debug = true)]
|
||||
struct DebugLogErrorJob : IJob
|
||||
{
|
||||
public void Execute()
|
||||
{
|
||||
UnityEngine.Debug.LogError("X");
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator DebugLogError()
|
||||
{
|
||||
LogAssert.Expect(LogType.Error, "X");
|
||||
|
||||
var jobData = new DebugLogErrorJob();
|
||||
jobData.Run();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
private struct SafetyCheckJobWithDomainReload : IJob
|
||||
{
|
||||
public NativeArray<int> Result;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
Result[0] = 1;
|
||||
SetResultWithSafetyChecksOnly();
|
||||
}
|
||||
|
||||
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
|
||||
private void SetResultWithSafetyChecksOnly()
|
||||
{
|
||||
Result[0] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
|
||||
private static void SafelySetSomeBool(ref bool b)
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
|
||||
[BurstCompile(DisableSafetyChecks = false)]
|
||||
private struct EnabledSafetyChecksJob : IJob
|
||||
{
|
||||
[WriteOnly] public NativeArray<int> WasHit;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
var b = false;
|
||||
SafelySetSomeBool(ref b);
|
||||
WasHit[0] = b ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile(DisableSafetyChecks = true)]
|
||||
private struct DisabledSafetyChecksJob : IJob
|
||||
{
|
||||
[WriteOnly] public NativeArray<int> WasHit;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
var b = false;
|
||||
SafelySetSomeBool(ref b);
|
||||
WasHit[0] = b ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOffGloballyAndOnInJob()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = false;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new EnabledSafetyChecksJob()
|
||||
{
|
||||
WasHit = new NativeArray<int>(1, Allocator.TempJob)
|
||||
};
|
||||
|
||||
job.Schedule().Complete();
|
||||
|
||||
try
|
||||
{
|
||||
// Safety checks are off globally which overwrites the job having safety checks on.
|
||||
Assert.AreEqual(0, job.WasHit[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.WasHit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOffGloballyAndOffInJob()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = false;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new DisabledSafetyChecksJob()
|
||||
{
|
||||
WasHit = new NativeArray<int>(1, Allocator.TempJob)
|
||||
};
|
||||
|
||||
job.Schedule().Complete();
|
||||
|
||||
try
|
||||
{
|
||||
// Safety checks are off globally and off in job.
|
||||
Assert.AreEqual(0, job.WasHit[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.WasHit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOnGloballyAndOnInJob()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new EnabledSafetyChecksJob()
|
||||
{
|
||||
WasHit = new NativeArray<int>(1, Allocator.TempJob)
|
||||
};
|
||||
|
||||
job.Schedule().Complete();
|
||||
|
||||
try
|
||||
{
|
||||
// Safety checks are on globally and on in job.
|
||||
Assert.AreEqual(1, job.WasHit[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.WasHit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOnGloballyAndOffInJob()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new DisabledSafetyChecksJob()
|
||||
{
|
||||
WasHit = new NativeArray<int>(1, Allocator.TempJob)
|
||||
};
|
||||
|
||||
job.Schedule().Complete();
|
||||
|
||||
try
|
||||
{
|
||||
// Safety checks are on globally but off in job.
|
||||
Assert.AreEqual(0, job.WasHit[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.WasHit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckForceSafetyChecksWorks()
|
||||
{
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
var job = new DisabledSafetyChecksJob()
|
||||
{
|
||||
WasHit = new NativeArray<int>(1, Allocator.TempJob)
|
||||
};
|
||||
|
||||
job.Schedule().Complete();
|
||||
|
||||
try
|
||||
{
|
||||
// Even though the job has set disabled safety checks, the menu item 'Force On'
|
||||
// has been set which overrides any other requested behaviour.
|
||||
Assert.AreEqual(1, job.WasHit[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
job.WasHit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSharedStaticWithDomainReload()
|
||||
{
|
||||
// Check that on a first access, SharedStatic is always empty
|
||||
AssertTestSharedStaticEmpty();
|
||||
|
||||
// Fill with some data
|
||||
TestSharedStatic.SharedValue.Data = new TestSharedStatic(1, 2, 3, 4);
|
||||
|
||||
Assert.AreEqual(1, TestSharedStatic.SharedValue.Data.Value1);
|
||||
Assert.AreEqual(2, TestSharedStatic.SharedValue.Data.Value2);
|
||||
Assert.AreEqual(3, TestSharedStatic.SharedValue.Data.Value3);
|
||||
Assert.AreEqual(4, TestSharedStatic.SharedValue.Data.Value4);
|
||||
|
||||
// Ask for domain reload
|
||||
EditorUtility.RequestScriptReload();
|
||||
|
||||
// Wait for the domain reload to be completed
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
// Make sure that after a domain reload everything is initialized back to zero
|
||||
AssertTestSharedStaticEmpty();
|
||||
}
|
||||
|
||||
private static void AssertTestSharedStaticEmpty()
|
||||
{
|
||||
Assert.AreEqual(0, TestSharedStatic.SharedValue.Data.Value1);
|
||||
Assert.AreEqual(0, TestSharedStatic.SharedValue.Data.Value2);
|
||||
Assert.AreEqual(0, TestSharedStatic.SharedValue.Data.Value3);
|
||||
Assert.AreEqual(0, TestSharedStatic.SharedValue.Data.Value4);
|
||||
}
|
||||
|
||||
private struct TestSharedStatic
|
||||
{
|
||||
public static readonly SharedStatic<TestSharedStatic> SharedValue = SharedStatic<TestSharedStatic>.GetOrCreate<TestSharedStatic>();
|
||||
|
||||
public TestSharedStatic(int value1, long value2, long value3, long value4)
|
||||
{
|
||||
Value1 = value1;
|
||||
Value2 = value2;
|
||||
Value3 = value3;
|
||||
Value4 = value4;
|
||||
}
|
||||
|
||||
public int Value1;
|
||||
public long Value2;
|
||||
public long Value3;
|
||||
public long Value4;
|
||||
}
|
||||
|
||||
static EditModeTest()
|
||||
{
|
||||
// UnityEngine.Debug.Log("Domain Reload");
|
||||
}
|
||||
[BurstCompile]
|
||||
private static class FunctionPointers
|
||||
{
|
||||
public delegate int SafetyChecksDelegate();
|
||||
|
||||
[BurstCompile(DisableSafetyChecks = false)]
|
||||
public static int WithSafetyChecksEnabled()
|
||||
{
|
||||
var b = false;
|
||||
SafelySetSomeBool(ref b);
|
||||
return b ? 1 : 0;
|
||||
}
|
||||
|
||||
[BurstCompile(DisableSafetyChecks = true)]
|
||||
public static int WithSafetyChecksDisabled()
|
||||
{
|
||||
var b = false;
|
||||
SafelySetSomeBool(ref b);
|
||||
return b ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOffGloballyAndOffInFunctionPointer()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = false;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var funcPtr = BurstCompiler.CompileFunctionPointer<FunctionPointers.SafetyChecksDelegate>(FunctionPointers.WithSafetyChecksDisabled);
|
||||
|
||||
// Safety Checks are off globally and off in the job.
|
||||
Assert.AreEqual(0, funcPtr.Invoke());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOffGloballyAndOnInFunctionPointer()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = false;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var funcPtr = BurstCompiler.CompileFunctionPointer<FunctionPointers.SafetyChecksDelegate>(FunctionPointers.WithSafetyChecksEnabled);
|
||||
|
||||
// Safety Checks are off globally and on in job, but the global setting takes precedence.
|
||||
Assert.AreEqual(0, funcPtr.Invoke());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOnGloballyAndOffInFunctionPointer()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var funcPtr = BurstCompiler.CompileFunctionPointer<FunctionPointers.SafetyChecksDelegate>(FunctionPointers.WithSafetyChecksDisabled);
|
||||
|
||||
// Safety Checks are on globally and off in the job, so the job takes predence.
|
||||
Assert.AreEqual(0, funcPtr.Invoke());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckSafetyChecksOnGloballyAndOnInFunctionPointer()
|
||||
{
|
||||
BurstCompiler.Options.EnableBurstSafetyChecks = true;
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
var funcPtr = BurstCompiler.CompileFunctionPointer<FunctionPointers.SafetyChecksDelegate>(FunctionPointers.WithSafetyChecksEnabled);
|
||||
|
||||
// Safety Checks are on globally and on in the job.
|
||||
Assert.AreEqual(1, funcPtr.Invoke());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckFunctionPointerForceSafetyChecksWorks()
|
||||
{
|
||||
BurstCompiler.Options.ForceEnableBurstSafetyChecks = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
var funcPtr = BurstCompiler.CompileFunctionPointer<FunctionPointers.SafetyChecksDelegate>(FunctionPointers.WithSafetyChecksDisabled);
|
||||
|
||||
// Even though the job has set disabled safety checks, the menu item 'Force On'
|
||||
// has been set which overrides any other requested behaviour.
|
||||
Assert.AreEqual(1, funcPtr.Invoke());
|
||||
}
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
private struct DebugDrawLineJob : IJob
|
||||
{
|
||||
public void Execute()
|
||||
{
|
||||
Debug.DrawLine(new Vector3(0, 0, 0), new Vector3(5, 0, 0), Color.green);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDebugDrawLine()
|
||||
{
|
||||
var job = new DebugDrawLineJob();
|
||||
job.Schedule().Complete();
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private static class ProfilerMarkerWrapper
|
||||
{
|
||||
private static readonly ProfilerMarker StaticMarker = new ProfilerMarker("TestStaticBurst");
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
public static int CreateAndUseProfilerMarker(int start)
|
||||
{
|
||||
using (StaticMarker.Auto())
|
||||
{
|
||||
var p = new ProfilerMarker("TestBurst");
|
||||
p.Begin();
|
||||
var result = 0;
|
||||
for (var i = start; i < start + 100000; i++)
|
||||
{
|
||||
result += i;
|
||||
}
|
||||
p.End();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private delegate int IntReturnIntDelegate(int param);
|
||||
|
||||
[Test]
|
||||
public void TestCreateProfilerMarker()
|
||||
{
|
||||
var fp = BurstCompiler.CompileFunctionPointer<IntReturnIntDelegate>(ProfilerMarkerWrapper.CreateAndUseProfilerMarker);
|
||||
fp.Invoke(5);
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
private static class EnsureAssemblyBuilderDoesNotInvalidFunctionPointers
|
||||
{
|
||||
[BurstDiscard]
|
||||
private static void MessOnManaged(ref int x) => x = 42;
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
public static int WithBurst()
|
||||
{
|
||||
int x = 13;
|
||||
MessOnManaged(ref x);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY_2023_1_OR_NEWER
|
||||
[Test]
|
||||
public void TestAssemblyBuilder()
|
||||
{
|
||||
var preBuilder = EnsureAssemblyBuilderDoesNotInvalidFunctionPointers.WithBurst();
|
||||
Assert.AreEqual(13, preBuilder);
|
||||
|
||||
var tempDirectory = Path.GetTempPath();
|
||||
|
||||
var script = Path.Combine(tempDirectory, "BurstGeneratedAssembly.cs");
|
||||
|
||||
File.WriteAllText(script, @"
|
||||
using Unity.Burst;
|
||||
|
||||
namespace BurstGeneratedAssembly
|
||||
{
|
||||
[BurstCompile]
|
||||
public static class MyStuff
|
||||
{
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
public static int BurstedFunction(int x) => x + 1;
|
||||
}
|
||||
}
|
||||
|
||||
");
|
||||
|
||||
var dll = Path.Combine(tempDirectory, "BurstGeneratedAssembly.dll");
|
||||
|
||||
var builder = new AssemblyBuilder(dll, script);
|
||||
|
||||
Assert.IsTrue(builder.Build());
|
||||
|
||||
// Busy wait for the build to be done.
|
||||
while (builder.status != AssemblyBuilderStatus.Finished)
|
||||
{
|
||||
Assert.AreEqual(preBuilder, EnsureAssemblyBuilderDoesNotInvalidFunctionPointers.WithBurst());
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
Assert.AreEqual(preBuilder, EnsureAssemblyBuilderDoesNotInvalidFunctionPointers.WithBurst());
|
||||
}
|
||||
#endif
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CheckChangingScriptOptimizationMode()
|
||||
{
|
||||
static void CheckBurstIsEnabled()
|
||||
{
|
||||
using (var jobTester = new BurstJobTester2())
|
||||
{
|
||||
var result = jobTester.Calculate();
|
||||
Assert.AreNotEqual(0.0f, result);
|
||||
}
|
||||
}
|
||||
|
||||
CheckBurstIsEnabled();
|
||||
|
||||
// Switch scripting code optimization mode from Release to Debug.
|
||||
Assert.AreEqual(CodeOptimization.Release, CompilationPipeline.codeOptimization);
|
||||
CompilationPipeline.codeOptimization = CodeOptimization.Debug;
|
||||
|
||||
// Wait for the domain reload to be completed
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
CheckBurstIsEnabled();
|
||||
|
||||
// Set scripting code optimization mode back to Release.
|
||||
CompilationPipeline.codeOptimization = CodeOptimization.Release;
|
||||
|
||||
// Wait for the domain reload to be completed
|
||||
yield return new WaitForDomainReload();
|
||||
|
||||
CheckBurstIsEnabled();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 581193df6bcc393285dee7fedd436195
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,777 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Unity.Burst.Editor;
|
||||
using System.Text;
|
||||
using Unity.Burst;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
||||
[TestFixture]
|
||||
public class LongTextAreaTests
|
||||
{
|
||||
private LongTextArea _textArea;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_textArea = new LongTextArea();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("", " push rbp\n .seh_pushreg rbp\n", 7, true)]
|
||||
[TestCase("<color=#CCCCCC>", " push rbp\n .seh_pushreg rbp\n", 25, true)]
|
||||
[TestCase("<color=#d7ba7d>", " push rbp\n .seh_pushreg rbp\n", 21 + 15 + 8 + 15, true)]
|
||||
[TestCase("", "\n# hulahop hejsa\n", 5, false)]
|
||||
public void GetStartingColorTagTest(string tag, string text, int textIdx, bool syntaxHighlight)
|
||||
{
|
||||
var disAssembler = new BurstDisassembler();
|
||||
_textArea.SetText("", text, true, disAssembler, disAssembler.Initialize(text, BurstDisassembler.AsmKind.Intel, true, syntaxHighlight));
|
||||
if (!_textArea.CopyColorTags) _textArea.ChangeCopyMode();
|
||||
|
||||
Assert.That(_textArea.GetStartingColorTag(0, textIdx), Is.EqualTo(tag));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("", " push rbp\n .seh_pushreg rbp\n", 7, true)]
|
||||
[TestCase("</color>", " push rbp\n .seh_pushreg rbp\n", 25, true)]
|
||||
[TestCase("</color>", " push rbp\n .seh_pushreg rbp\n", 21 + 15 + 8 + 15, true)]
|
||||
[TestCase("", " push rbp\n .seh_pushreg rbp\n", 14 + 15 + 8, true)]
|
||||
[TestCase("", "\n# hulahop hejsa\n", 5, false)]
|
||||
public void GetEndingColorTagTest(string tag, string text, int textIdx, bool syntaxHighlight)
|
||||
{
|
||||
var disAssembler = new BurstDisassembler();
|
||||
_textArea.SetText("", text, true, disAssembler, disAssembler.Initialize(text, BurstDisassembler.AsmKind.Intel, true, syntaxHighlight));
|
||||
if (!_textArea.CopyColorTags) _textArea.ChangeCopyMode();
|
||||
|
||||
Assert.That(_textArea.GetEndingColorTag(0, textIdx), Is.EqualTo(tag));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("<color=#FFFF00>hulahop</color> <color=#DCDCAA>hejsa</color>\n", 0, 16, 16)]
|
||||
[TestCase("<color=#FFFF00>hulahop</color>\n <color=#DCDCAA>hejsa</color>\n", 1, 40, 9)]
|
||||
[TestCase("<color=#FFFF00>hulahop</color>\n <color=#DCDCAA>hejsa</color>\n hej", 2, 67, 3)]
|
||||
[TestCase("<color=#FFFF00>hulahop</color> <color=#DCDCAA>hejsa</color>", 0, 15, 15)]
|
||||
[TestCase("\n <color=#4EC9B0>je</color> <color=#d4d4d4>.LBB11_4</color>", 1, 34, 33)]
|
||||
// Test cases for when on enhanced text and not coloured.
|
||||
[TestCase("hulahop hejsa\n", 0, 16, 16)]
|
||||
[TestCase("hulahop\n hejsa\n", 1, 17, 9)]
|
||||
[TestCase("hulahop\n hejsa\n hej", 2, 21, 3)]
|
||||
[TestCase("hulahop hejsa", 0, 15, 15)]
|
||||
public void GetEndIndexOfColoredLineTest(string text, int line, int resTotal, int resRel)
|
||||
{
|
||||
Assert.That(_textArea.GetEndIndexOfColoredLine(text, line), Is.EqualTo((resTotal, resRel)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("hulahop hejsa\n", 0, 16, 16)]
|
||||
[TestCase("hulahop\n hejsa\n", 1, 17, 9)]
|
||||
[TestCase("hulahop\n hejsa\n hej", 2, 21, 3)]
|
||||
[TestCase("hulahop hejsa", 0, 15, 15)]
|
||||
[TestCase("\nhulahop hejsa", 1, 16, 15)]
|
||||
public void GetEndIndexOfPlainLineTest(string text, int line, int resTotal, int resRel)
|
||||
{
|
||||
Assert.That(_textArea.GetEndIndexOfPlainLine(text, line), Is.EqualTo((resTotal, resRel)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("<color=#FFFF00>hulahop</color>\n <color=#DCDCAA>hejsa</color>\n hej", 2, 2, 0)]
|
||||
[TestCase("<color=#FFFF00>hulahop</color>\n <color=#DCDCAA>hejsa</color>\n hej", 1, 5, 15)]
|
||||
[TestCase("<color=#FFFF00>hulahop</color> <color=#DCDCAA>hejsa</color>:", 0, 17, 46)]
|
||||
public void BumpSelectionXByColortagTest(string text, int lineNum, int charsIn, int colourTagFiller)
|
||||
{
|
||||
var (idxTotal, idxRel) = _textArea.GetEndIndexOfColoredLine(text, lineNum);
|
||||
Assert.That(_textArea.BumpSelectionXByColorTag(text, idxTotal - idxRel, charsIn), Is.EqualTo(charsIn + colourTagFiller));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(" push rbp\n .seh_pushreg rbp\n", false)]
|
||||
[TestCase(" push rbp\n .seh_pushreg rbp\n", true)]
|
||||
public void SelectAllTest(string text, bool useDisassembler)
|
||||
{
|
||||
if (useDisassembler)
|
||||
{
|
||||
var disAssembler = new BurstDisassembler();
|
||||
_textArea.SetText("", text, true, disAssembler, disAssembler.Initialize(text, BurstDisassembler.AsmKind.Intel));
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_textArea.SetText("", text, true, null, false);
|
||||
}
|
||||
|
||||
|
||||
_textArea.selectPos = new Vector2(2, 2);
|
||||
// There is no inserted comments or similar in my test example, so finalAreaSize, should be equivalent for the two.
|
||||
_textArea.finalAreaSize = new Vector2(7.5f * text.Length, 15.2f);
|
||||
|
||||
_textArea.SelectAll();
|
||||
Assert.That(_textArea.selectPos, Is.EqualTo(Vector2.zero));
|
||||
Assert.That(_textArea.selectDragPos, Is.EqualTo(new Vector2(7.5f * text.Length, 15.2f)));
|
||||
|
||||
if (!useDisassembler)
|
||||
{
|
||||
Assert.That(_textArea.textSelectionIdx, Is.EqualTo((0, text.Length)));
|
||||
}
|
||||
}
|
||||
|
||||
private BurstDisassembler GetDisassemblerandText(string compileTargetName, int debugLvl, out string textToRender)
|
||||
{
|
||||
// Get target job assembly:
|
||||
var assemblies = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs;
|
||||
var result = BurstReflection.FindExecuteMethods(assemblies, BurstReflectionAssemblyOptions.None);
|
||||
var compileTarget = result.CompileTargets.Find(x => x.GetDisplayName() == compileTargetName);
|
||||
|
||||
Assert.IsTrue(compileTarget != default, $"Could not find compile target: {compileTarget}");
|
||||
|
||||
BurstDisassembler disassembler = new BurstDisassembler();
|
||||
|
||||
var options = new StringBuilder();
|
||||
|
||||
compileTarget.Options.TryGetOptions(compileTarget.JobType, true, out string defaultOptions);
|
||||
options.AppendLine(defaultOptions);
|
||||
// Disables the 2 current warnings generated from code (since they clutter up the inspector display)
|
||||
// BC1370 - throw inside code not guarded with ConditionalSafetyCheck attribute
|
||||
// BC1322 - loop intrinsic on loop that has been optimised away
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDisableWarnings, "BC1370;BC1322")}");
|
||||
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, BurstTargetCpu.X64_SSE4)}");
|
||||
|
||||
options.AppendLine($"{BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDebug, $"{debugLvl}")}");
|
||||
|
||||
var baseOptions = options.ToString();
|
||||
|
||||
var append = BurstInspectorGUI.GetDisasmOptions()[(int)DisassemblyKind.Asm];
|
||||
|
||||
// Setup disAssembler with the job:
|
||||
compileTarget.RawDisassembly = BurstInspectorGUI.GetDisassembly(compileTarget.Method, baseOptions + append);
|
||||
textToRender = compileTarget.RawDisassembly.TrimStart('\n');
|
||||
|
||||
return disassembler;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(true, true, 2)]
|
||||
[TestCase(true, true, 1)]
|
||||
[TestCase(true, false, 2)]
|
||||
[TestCase(true, false, 1)]
|
||||
[TestCase(false, true, 2)]
|
||||
[TestCase(false, true, 1)]
|
||||
[TestCase(false, false, 2)]
|
||||
[TestCase(false, false, 1)]
|
||||
public void CopyAllTest(bool useDisassembler, bool coloured, int debugLvl)
|
||||
{
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
|
||||
if (useDisassembler)
|
||||
{
|
||||
_textArea.SetText("", textToRender, true, disassembler, disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel, true, coloured));
|
||||
_textArea.ExpandAllBlocks();
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < disassembler.Blocks.Count; i++)
|
||||
{
|
||||
builder.Append(disassembler.GetOrRenderBlockToText(i));
|
||||
}
|
||||
|
||||
textToRender = builder.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
_textArea.SetText("", textToRender, true, null, false);
|
||||
}
|
||||
|
||||
_textArea.Layout(GUIStyle.none, _textArea.horizontalPad);
|
||||
|
||||
_textArea.SelectAll();
|
||||
_textArea.DoSelectionCopy();
|
||||
|
||||
Assert.AreEqual(textToRender, EditorGUIUtility.systemCopyBuffer);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyAllTextWithoutColorTagsTest()
|
||||
{
|
||||
// Setup:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
_textArea.Layout(GUIStyle.none, _textArea.horizontalPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, true);
|
||||
|
||||
// Actual test to reproduce error:
|
||||
_textArea.ChangeCopyMode();
|
||||
_textArea.SelectAll();
|
||||
Assert.DoesNotThrow(_textArea.DoSelectionCopy);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyTextAfterSelectionMovedTest()
|
||||
{
|
||||
// Setup:
|
||||
const bool sbm = true;
|
||||
var wa = Rect.zero;
|
||||
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
_textArea.Layout(GUIStyle.none, _textArea.horizontalPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, sbm);
|
||||
|
||||
// Actual test to reproduce error:
|
||||
_textArea.ChangeCopyMode();
|
||||
|
||||
_textArea.MoveSelectionDown(wa, sbm);
|
||||
_textArea.MoveSelectionDown(wa, sbm);
|
||||
_textArea.MoveSelectionLeft(wa, sbm);
|
||||
|
||||
Assert.DoesNotThrow(_textArea.DoSelectionCopy);
|
||||
|
||||
_textArea.MoveSelectionRight(wa, sbm);
|
||||
Assert.DoesNotThrow(_textArea.DoSelectionCopy);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyTextIdenticalWithAndWithoutColorTags()
|
||||
{
|
||||
// We don't wanna go messing with the users system buffer. At least if user didn't break anything.
|
||||
var savedSystemBuffer = EditorGUIUtility.systemCopyBuffer;
|
||||
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
_textArea.Layout(GUIStyle.none, _textArea.horizontalPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, true);
|
||||
for (var i=0; i<disassembler.Blocks[0].Length+50; i++) _textArea.MoveSelectionDown(Rect.zero, true);
|
||||
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, true);
|
||||
_textArea.UpdateEnhancedSelectTextIdx(_textArea.horizontalPad);
|
||||
|
||||
_textArea.DoSelectionCopy();
|
||||
var copiedText1 = EditorGUIUtility.systemCopyBuffer;
|
||||
|
||||
_textArea.ChangeCopyMode();
|
||||
_textArea.DoSelectionCopy();
|
||||
var copiedText2 = EditorGUIUtility.systemCopyBuffer;
|
||||
|
||||
var regx = new Regex(@"(<color=#[0-9A-Za-z]*>)|(</color>)");
|
||||
|
||||
if (!_textArea.CopyColorTags)
|
||||
{
|
||||
(copiedText1, copiedText2) = (copiedText2, copiedText1);
|
||||
}
|
||||
copiedText2 = regx.Replace(copiedText2, "");
|
||||
|
||||
EditorGUIUtility.systemCopyBuffer = savedSystemBuffer;
|
||||
Assert.AreEqual(copiedText1, copiedText2,
|
||||
"Copy with color tags did not match copy without " +
|
||||
"(Color tags is removed from the copy to make it comparable with the color-tag-less copy).");
|
||||
}
|
||||
|
||||
// Disabled due to https://jira.unity3d.com/browse/BUR-2207
|
||||
[Test]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void KeepingSelectionWhenMovingTest(bool useDisassembler)
|
||||
{
|
||||
const string jobName = "BurstInspectorGUITests.MyJob - (IJob)";
|
||||
BurstDisassembler disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
Rect workingArea = new Rect();
|
||||
|
||||
if (useDisassembler)
|
||||
{
|
||||
_textArea.SetText(jobName, textToRender, true, disassembler, disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel));
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, workingArea, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_textArea.SetText(jobName, textToRender, false, null, false);
|
||||
}
|
||||
_textArea.Layout(GUIStyle.none, _textArea.horizontalPad);
|
||||
|
||||
Assert.IsFalse(_textArea.HasSelection);
|
||||
|
||||
Vector2 start = _textArea.selectDragPos;
|
||||
if (useDisassembler) start.x = _textArea.horizontalPad + _textArea.fontWidth / 2;
|
||||
|
||||
// Horizontal movement:
|
||||
_textArea.MoveSelectionRight(workingArea, true);
|
||||
Assert.IsTrue(_textArea.HasSelection);
|
||||
Assert.AreEqual(start + new Vector2(_textArea.fontWidth, 0), _textArea.selectDragPos);
|
||||
|
||||
_textArea.MoveSelectionLeft(workingArea, true);
|
||||
Assert.IsTrue(_textArea.HasSelection);
|
||||
Assert.AreEqual(start, _textArea.selectDragPos);
|
||||
|
||||
// Vertical movement:
|
||||
_textArea.MoveSelectionDown(workingArea, true);
|
||||
Assert.IsTrue(_textArea.HasSelection);
|
||||
Assert.AreEqual(start + new Vector2(0, _textArea.fontHeight), _textArea.selectDragPos);
|
||||
|
||||
_textArea.MoveSelectionUp(workingArea, true);
|
||||
Assert.IsTrue(_textArea.HasSelection);
|
||||
Assert.AreEqual(start, _textArea.selectDragPos);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFragNrFromBlockIdxTest()
|
||||
{
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel, false, false));
|
||||
|
||||
|
||||
var garbageVariable = 0f;
|
||||
var numBlocks = disassembler.Blocks.Count;
|
||||
|
||||
// Want to get the last fragment possible
|
||||
var expectedFragNr = 0;
|
||||
for (var i = 0; i < _textArea.blocksFragmentsPlain.Length-1; i++)
|
||||
{
|
||||
expectedFragNr += _textArea.GetPlainFragments(i).Count;
|
||||
}
|
||||
|
||||
Assert.AreEqual(expectedFragNr, _textArea.GetFragNrFromBlockIdx(numBlocks-1, 0, 0, ref garbageVariable));
|
||||
|
||||
Assert.AreEqual(3, _textArea.GetFragNrFromBlockIdx(3, 1, 1, ref garbageVariable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFragNrFromEnhancedTextIdxTest()
|
||||
{
|
||||
const string jobName = "BurstJobTester2.MyJob - (IJob)";
|
||||
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
_textArea.SetText(jobName, textToRender, true, disassembler,
|
||||
disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel, false, false));
|
||||
|
||||
var garbageVariable = 0f;
|
||||
const int blockIdx = 2;
|
||||
|
||||
var fragments = _textArea.RecomputeFragmentsFromBlock(blockIdx);
|
||||
var text = _textArea.GetText;
|
||||
var expectedFrag = blockIdx + fragments.Count - 1;
|
||||
|
||||
var info = disassembler.BlockIdxs[blockIdx];
|
||||
|
||||
var extraFragLen = fragments.Count > 1
|
||||
? fragments[0].text.Length + 1 // job only contains 2 fragments at max
|
||||
: 0;
|
||||
|
||||
var idx = info.startIdx + extraFragLen + 1;
|
||||
|
||||
var expected = (expectedFrag, info.startIdx + extraFragLen);
|
||||
var actual = _textArea.GetFragNrFromEnhancedTextIdx(idx, 0, 0, 0, ref garbageVariable);
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void SearchTextEnhancedTest(bool colored)
|
||||
{
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
_textArea.SetText("", textToRender, true, disassembler, disassembler.Initialize(textToRender, BurstDisassembler.AsmKind.Intel, true, colored));
|
||||
|
||||
var workingArea = new Rect(0, 0, 10, 10);
|
||||
_textArea.SearchText(new SearchCriteria(".Ltmp.:", true, false, true), new Regex(@"\.Ltmp.:"), ref workingArea);
|
||||
|
||||
Assert.AreEqual(10, _textArea.NrSearchHits);
|
||||
|
||||
// Check that they are filled out probably
|
||||
int nr = 0;
|
||||
foreach (var fragHits in _textArea.searchHits.Values)
|
||||
{
|
||||
foreach (var hit in fragHits)
|
||||
{
|
||||
Assert.AreEqual((0, 7, nr++), hit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectOnOneLineTest()
|
||||
{
|
||||
const string testCase = "\n<color=#d4d4d4>.Ltmp12</color>: ...";
|
||||
|
||||
var disassembler = new BurstDisassembler();
|
||||
_textArea.SetText("", testCase, false, disassembler, disassembler.Initialize(testCase, BurstDisassembler.AsmKind.Intel));
|
||||
|
||||
// Set fontWidth and fontHeight
|
||||
_textArea.Layout(GUIStyle.none, 20f);
|
||||
|
||||
// Set selection markers.
|
||||
// Error happened when selection started at the lowest point of a line.
|
||||
_textArea.selectPos = new Vector2(0, _textArea.fontHeight);
|
||||
// Select further down to make sure it wont be switched with selectPos.
|
||||
_textArea.selectDragPos = new Vector2(10 * _textArea.fontWidth, _textArea.fontHeight*2);
|
||||
|
||||
// Hopefully it wont throw anything
|
||||
Assert.DoesNotThrow(() =>
|
||||
_textArea.PrepareInfoForSelection(0, 0, _textArea.fontHeight,
|
||||
new LongTextArea.Fragment() { text = testCase.TrimStart('\n'), lineCount = 1 },
|
||||
_textArea.GetEndIndexOfColoredLine));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetLineHighlightTest()
|
||||
{
|
||||
const float hPad = 20f;
|
||||
const int linePressed = 4 + 13;
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
// Set up dependencies for GetLineHighlight(.)
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,0, _textArea.fontWidth*50,_textArea.fontHeight*50),
|
||||
false
|
||||
);
|
||||
|
||||
// Setup simple cache.
|
||||
var cache = new LongTextArea.LineRegRectsCache();
|
||||
var rect = _textArea.GetLineHighlight(ref cache, hPad, linePressed);
|
||||
Assert.IsFalse(cache.IsRegistersCached(linePressed));
|
||||
Assert.IsTrue(cache.IsLineHighlightCached(linePressed, false));
|
||||
|
||||
var expectedX = hPad;
|
||||
var b = 0;
|
||||
for (; b < disassembler.Blocks.Count; b++)
|
||||
{
|
||||
if (disassembler.Blocks[b].LineIndex > linePressed)
|
||||
{
|
||||
b--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var expectedY = (_textArea.blockLine[b] + (linePressed - disassembler.Blocks[b].LineIndex)) * _textArea.fontHeight + _textArea.fontHeight;
|
||||
var lineStr = _textArea.GetLineString(disassembler.Lines[linePressed]);
|
||||
var lineLen = lineStr.Length * _textArea.fontWidth;
|
||||
|
||||
var expected = new Rect(expectedX,
|
||||
expectedY,
|
||||
lineLen,
|
||||
2f
|
||||
);
|
||||
|
||||
var result = Mathf.Approximately(expectedX, rect.x)
|
||||
&& Mathf.Approximately(expectedY, rect.y)
|
||||
&& Mathf.Approximately(lineLen, rect.width)
|
||||
&& Mathf.Approximately(2f, rect.height);
|
||||
|
||||
Assert.IsTrue(result, $"line highlight for \"{lineStr}\" was wrong.\nExpected: {expected}\nBut was: {rect}");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void GetRegRectsTest()
|
||||
{
|
||||
#region Initialize-test-states
|
||||
const float hPad = 20f;
|
||||
const int linePressed = 8 + 13;
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
// Set up dependencies for GetLineHighlight(.)
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
// Setting up variables to determine view size:
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, false);
|
||||
#endregion
|
||||
|
||||
// Find the block index to put within view:
|
||||
var blockIdx = disassembler.Blocks.Count/2;
|
||||
for (; blockIdx > 0; blockIdx--)
|
||||
{
|
||||
// Take the first block where we know the lastLine will be in the next block.
|
||||
if (!_textArea._folded[blockIdx + 1] && disassembler.Blocks[blockIdx].Length >= 5) break;
|
||||
}
|
||||
// Initialize states with regards to view:
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,0, _textArea.fontWidth*100,_textArea.fontHeight*(_textArea.blockLine[blockIdx]+1)),
|
||||
false
|
||||
);
|
||||
|
||||
#region Function-to-test-call
|
||||
var cache = new LongTextArea.LineRegRectsCache();
|
||||
var registersUsed = new List<string> { "rbp", "rsp" };
|
||||
var rects = _textArea.GetRegisterRects(hPad, ref cache, linePressed, registersUsed);
|
||||
#endregion
|
||||
#region Expected-variables
|
||||
var lastLine = disassembler.Blocks[_textArea._renderBlockEnd+1].LineIndex + 4;
|
||||
|
||||
var expectedRbp =
|
||||
(from pair in disassembler._registersUsedAtLine._linesRegisters.TakeWhile(x => x.Key < lastLine)
|
||||
where pair.Value.Contains("rbp") && disassembler.Lines[pair.Key].Kind != BurstDisassembler.AsmLineKind.Directive
|
||||
select pair);
|
||||
var expectedRsp =
|
||||
(from pair in disassembler._registersUsedAtLine._linesRegisters.TakeWhile(x => x.Key < lastLine)
|
||||
where pair.Value.Contains("rsp") && disassembler.Lines[pair.Key].Kind != BurstDisassembler.AsmLineKind.Directive
|
||||
select pair);
|
||||
|
||||
// Check that they are correctly placed!
|
||||
// Only check the last here, as under development the "hardest" behaviour was from within the lowest blocks.
|
||||
var lastRectLineIdx = expectedRbp.Last().Key;
|
||||
var lastRectLine = disassembler.Lines[lastRectLineIdx];
|
||||
var lastRectLineStr = _textArea.GetLineString(lastRectLine);
|
||||
|
||||
var expectedX = lastRectLineStr.Substring(0, lastRectLineStr.IndexOf("rbp")).Length * _textArea.fontWidth + hPad + 2f;
|
||||
#endregion
|
||||
|
||||
Assert.IsTrue(cache.IsRegistersCached(linePressed), "Register Rect cache not probarly setup.");
|
||||
Assert.IsFalse(cache.IsLineHighlightCached(linePressed, false), "Line highlight cache faultily set to cached.");
|
||||
|
||||
Assert.AreEqual(2, rects.Length, "Register Rect cache does not have correct number of registered registers.");
|
||||
Assert.AreEqual(expectedRbp.Count(), rects[0].Count, "Did not find all \"rbp\" registers.");
|
||||
Assert.AreEqual(expectedRsp.Count(), rects[1].Count, "Did not find all \"rsp\" registers.");
|
||||
Assert.That(rects[0][rects[0].Count - 1].x, Is.EqualTo(expectedX).Using(FloatEqualityComparer.Instance),
|
||||
"Wrong x position for last found \"rbp\" rect.");
|
||||
// Note: Does not check Y position, as this is highly dependent on architecture, making it annoyingly hard
|
||||
// to reason about.
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void RegsRectCacheTest()
|
||||
{
|
||||
const float hPad = 20f;
|
||||
const int linePressed = 8 + 13;
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
// Set up dependencies for GetLineHighlight(.)
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
var yStart = 0f;
|
||||
var yHeight = _textArea.fontHeight*44;
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,yStart, _textArea.fontWidth*100,yHeight),
|
||||
false
|
||||
);
|
||||
|
||||
var cache = new LongTextArea.LineRegRectsCache();
|
||||
var registersUsed = new List<string> { "rbp", "rsp" };
|
||||
var rects = _textArea.GetRegisterRects(hPad, ref cache, linePressed, registersUsed);
|
||||
Assert.IsTrue(cache.IsRegistersCached(linePressed));
|
||||
var cachedItems =
|
||||
(from elm in rects
|
||||
select elm.Count).Sum();
|
||||
|
||||
yStart = yHeight;
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,yStart, _textArea.fontWidth*100,yHeight),
|
||||
false
|
||||
);
|
||||
|
||||
rects = _textArea.GetRegisterRects(hPad, ref cache, linePressed, registersUsed);
|
||||
Assert.IsTrue(cache.IsRegistersCached(linePressed));
|
||||
var cachedItems2 =
|
||||
(from elm in rects
|
||||
select elm.Count).Sum();
|
||||
Assert.IsTrue(cachedItems2 >= cachedItems);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("\n xor r9d, r9d\n", "r9d")]
|
||||
[TestCase("\n push edx rdx\n", "rdx")]
|
||||
public void SameRegisterUsedTwiceTest(string line, string reg)
|
||||
{
|
||||
const float hPad = 20f;
|
||||
const int linePressed = 0;
|
||||
|
||||
// Get target job assembly:
|
||||
var disassembler = new BurstDisassembler();
|
||||
|
||||
// Set up dependencies for GetLineHighlight(.)
|
||||
_textArea.SetText("", line, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
line,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
var yStart = 0f;
|
||||
var yHeight = _textArea.fontHeight;
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,yStart, _textArea.fontWidth*100,yHeight),
|
||||
false
|
||||
);
|
||||
|
||||
var cache = new LongTextArea.LineRegRectsCache();
|
||||
var registersUsed = new List<string> { reg };
|
||||
var rects = _textArea.GetRegisterRects(hPad, ref cache, linePressed, registersUsed);
|
||||
Assert.IsTrue(cache.IsRegistersCached(linePressed));
|
||||
Assert.IsTrue(rects.Length == 1);
|
||||
Assert.IsTrue(rects[0].Count == 2, "Did not find exactly both registers.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test should check whether line press information is cleared when it is necessary.
|
||||
/// It does not check whether it is unnecessarily cleared.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ClearLinePressTest()
|
||||
{
|
||||
void SetupCache(float pad, int lineNr, ref LongTextArea.LineRegRectsCache cache, List<string> regsUsed)
|
||||
{
|
||||
_textArea._pressedLine = lineNr;
|
||||
_ = _textArea.GetRegisterRects(pad, ref cache, lineNr, regsUsed);
|
||||
_ = _textArea.GetLineHighlight(ref cache, pad, lineNr);
|
||||
}
|
||||
|
||||
// Test setup:
|
||||
var registersUsed = new List<string> { "rbp", "rsp" };
|
||||
const float hPad = 20f;
|
||||
const int linePressed = 4 + 13;
|
||||
|
||||
var disassembler = new BurstDisassembler();
|
||||
var thisPath = Path.GetDirectoryName(GetThisFilePath());
|
||||
Assert.NotNull(thisPath, "Could not retrieve path for current directory.");
|
||||
var textToRender = File.ReadAllText(Path.Combine(thisPath, _burstJobPath));
|
||||
|
||||
// Set up dependencies for GetLineHighlight(.)
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
|
||||
// Setting up variables to determine view size:
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none, Rect.zero, false);
|
||||
|
||||
var blockIdx = _textArea.GetLinesBlockIdx(linePressed);
|
||||
|
||||
_textArea.Layout(GUIStyle.none, hPad);
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,0, _textArea.fontWidth*100,_textArea.fontHeight*(_textArea.blockLine[blockIdx]+1)),
|
||||
false);
|
||||
|
||||
|
||||
void TestCache(bool isLineRect, bool isRect, bool isLine, string msg)
|
||||
{
|
||||
Assert.AreEqual(isLineRect,
|
||||
_textArea._lineRegCache.IsLineHighlightCached(linePressed, _textArea._folded[blockIdx]),
|
||||
msg + " Line highlight failed.");
|
||||
Assert.AreEqual(isRect,
|
||||
_textArea._lineRegCache.IsRegistersCached(linePressed),
|
||||
msg + " Register cache failed.");
|
||||
|
||||
msg += " Line press failed.";
|
||||
if (!isLine)
|
||||
{
|
||||
Assert.AreEqual(-1, _textArea._pressedLine, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreNotEqual(-1, _textArea._pressedLine, msg);
|
||||
}
|
||||
|
||||
SetupCache(hPad, linePressed, ref _textArea._lineRegCache, registersUsed);
|
||||
}
|
||||
|
||||
|
||||
SetupCache(hPad, linePressed, ref _textArea._lineRegCache, registersUsed);
|
||||
TestCache(true, true, true, "Initial setup failed.");
|
||||
|
||||
// Following changes should result in clearing everything, as assembly text might have changed:
|
||||
// * Expand all.
|
||||
_textArea.ExpandAllBlocks();
|
||||
TestCache(false, false, false, "Expanding blocks failed.");
|
||||
|
||||
// * Focus code.
|
||||
_textArea.FocusCodeBlocks();
|
||||
TestCache(false, false, false, "Focusing code blocks failed.");
|
||||
|
||||
// * disassembly kind, Target change, Safety check changes, Assembly kind changes e.g. by amount of debug info.
|
||||
_textArea.SetText("", textToRender, true, disassembler,
|
||||
disassembler.Initialize(
|
||||
textToRender,
|
||||
BurstDisassembler.AsmKind.Intel)
|
||||
);
|
||||
TestCache(false, false, false, "Setting up new text failed.");
|
||||
|
||||
// Following changes should only result in Rec change clear, as line number still resembles same line:
|
||||
// * Font size.
|
||||
_textArea.Invalidate();
|
||||
TestCache(false, false, true, "Changing font size failed.");
|
||||
|
||||
// * Show branch flow.
|
||||
_textArea.LayoutEnhanced(GUIStyle.none,
|
||||
new Rect(0,0, _textArea.fontWidth*100,_textArea.fontHeight*(_textArea.blockLine[blockIdx]+1)),
|
||||
true);
|
||||
TestCache(false, false, true, "Changing font size failed.");
|
||||
|
||||
// * Smell test (This will however clear everything as ´SetText()´ required).
|
||||
// Hence tested in the cases for fill clear.
|
||||
}
|
||||
|
||||
|
||||
private static string GetThisFilePath([CallerFilePath] string path = null) => path;
|
||||
private readonly string _burstJobPath = "burstTestTarget.txt";
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b866f2ae2314368d97e916270883416e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fa45014e48e13a5ea49fd421043ee143
|
||||
folderAsset: yes
|
|
@ -0,0 +1,16 @@
|
|||
public class BurstReflectionTestsSeparateAssembly
|
||||
{
|
||||
[Unity.Jobs.LowLevel.Unsafe.JobProducerType(typeof(MyJobProducerSeparateAssembly<,>))]
|
||||
public interface IMyGenericJobSeparateAssembly<T>
|
||||
{
|
||||
void Execute();
|
||||
}
|
||||
|
||||
private static class MyJobProducerSeparateAssembly<TJob, T>
|
||||
{
|
||||
public static void Execute(ref TJob job)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c07004be90d3814b9a09f7d08b26eb1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "SeparateAssembly",
|
||||
"references": [
|
||||
"Unity.Burst"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3ce0cf2654ad3464aa58eb2e27f77f0d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using Unity.Burst;
|
||||
|
||||
public static class TypeHashWrapper
|
||||
{
|
||||
public static int GetIntHash()
|
||||
{
|
||||
return BurstRuntime.GetHashCode32<int>();
|
||||
}
|
||||
|
||||
public static int GetGenericHash<T>()
|
||||
{
|
||||
return BurstRuntime.GetHashCode32<SomeStruct<T>>();
|
||||
}
|
||||
|
||||
public struct SomeStruct<T> { }
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 581a69eadade3f4985faa44d7b02aa3d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using Unity.Burst.Editor;
|
||||
|
||||
public class StringSliceTests
|
||||
{
|
||||
private const string _someText = "This is some text we are going to take StringSlice from.";
|
||||
private const string _target = "StringSlice";
|
||||
private readonly StringSlice _ssTarget = new StringSlice(_someText, _someText.IndexOf(_target, StringComparison.InvariantCulture), _target.Length);
|
||||
|
||||
[Test]
|
||||
public void StringSliceStringRepresentationTest()
|
||||
{
|
||||
Assert.AreEqual(_target, _ssTarget.ToString());
|
||||
Assert.AreEqual('S', _ssTarget[0]);
|
||||
Assert.IsTrue(_ssTarget == new StringSlice(_target));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StartsWithTest()
|
||||
{
|
||||
Assert.IsFalse(_ssTarget.StartsWith("This"));
|
||||
Assert.IsTrue(_ssTarget.StartsWith("S"));
|
||||
Assert.IsTrue(_ssTarget.StartsWith(_target));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContainsTest()
|
||||
{
|
||||
Assert.IsFalse(_ssTarget.Contains('T'));
|
||||
Assert.IsFalse(_ssTarget.Contains('s'));
|
||||
Assert.IsTrue(_ssTarget.Contains('S'));
|
||||
Assert.IsTrue(_ssTarget.Contains('g'));
|
||||
Assert.IsTrue(_ssTarget.Contains('e'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8361860cac3b3a12bc041994c9c1638c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "Unity.Burst.Editor.Tests",
|
||||
"references": [
|
||||
"Unity.Burst",
|
||||
"Unity.Mathematics",
|
||||
"Unity.Burst.Tests.UnitTests",
|
||||
"SeparateAssembly",
|
||||
"Unity.Burst.Editor"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 15ce69d7d9d9370c9704e0797a0ab06b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,662 @@
|
|||
.text
|
||||
.def @feat.00;
|
||||
.scl 3;
|
||||
.type 0;
|
||||
.endef
|
||||
.globl @feat.00
|
||||
.set @feat.00, 0
|
||||
.intel_syntax noprefix
|
||||
.file "main"
|
||||
.def burst.initialize;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl burst.initialize
|
||||
.p2align 4, 0x90
|
||||
burst.initialize:
|
||||
.Lfunc_begin0:
|
||||
.seh_proc burst.initialize
|
||||
push rbp
|
||||
.seh_pushreg rbp
|
||||
mov rbp, rsp
|
||||
.seh_setframe rbp, 0
|
||||
.seh_endprologue
|
||||
pop rbp
|
||||
ret
|
||||
.Lfunc_end0:
|
||||
.seh_endproc
|
||||
|
||||
.def burst.initialize.externals;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl burst.initialize.externals
|
||||
.p2align 4, 0x90
|
||||
burst.initialize.externals:
|
||||
.Lfunc_begin1:
|
||||
.seh_proc burst.initialize.externals
|
||||
push rbp
|
||||
.seh_pushreg rbp
|
||||
mov rbp, rsp
|
||||
.seh_setframe rbp, 0
|
||||
.seh_endprologue
|
||||
pop rbp
|
||||
ret
|
||||
.Lfunc_end1:
|
||||
.seh_endproc
|
||||
|
||||
.def burst.initialize.statics;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl burst.initialize.statics
|
||||
.p2align 4, 0x90
|
||||
burst.initialize.statics:
|
||||
.Lfunc_begin2:
|
||||
.seh_proc burst.initialize.statics
|
||||
push rbp
|
||||
.seh_pushreg rbp
|
||||
mov rbp, rsp
|
||||
.seh_setframe rbp, 0
|
||||
.seh_endprologue
|
||||
pop rbp
|
||||
ret
|
||||
.Lfunc_end2:
|
||||
.seh_endproc
|
||||
|
||||
.def d675c2aa053244579b646ec09368a505;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl d675c2aa053244579b646ec09368a505
|
||||
.p2align 4, 0x90
|
||||
d675c2aa053244579b646ec09368a505:
|
||||
.Lfunc_begin3:
|
||||
.seh_proc d675c2aa053244579b646ec09368a505
|
||||
push rbp
|
||||
.seh_pushreg rbp
|
||||
sub rsp, 48
|
||||
.seh_stackalloc 48
|
||||
lea rbp, [rsp + 48]
|
||||
.seh_setframe rbp, 48
|
||||
.seh_endprologue
|
||||
mov eax, dword ptr [rbp + 48]
|
||||
mov dword ptr [rsp + 32], eax
|
||||
call "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
nop
|
||||
add rsp, 48
|
||||
pop rbp
|
||||
ret
|
||||
.Lfunc_end3:
|
||||
.seh_endproc
|
||||
|
||||
.def "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
|
||||
.scl 3;
|
||||
.type 32;
|
||||
.endef
|
||||
.p2align 4, 0x90
|
||||
"Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null":
|
||||
.Lfunc_begin4:
|
||||
.cv_func_id 0
|
||||
.cv_file 1 "C:\\UnitySrc\\unity\\Runtime\\Jobs\\Managed\\IJob.cs"
|
||||
.cv_loc 0 1 57 0
|
||||
.seh_proc "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
push rbp
|
||||
.seh_pushreg rbp
|
||||
mov rbp, rsp
|
||||
.seh_setframe rbp, 0
|
||||
.seh_endprologue
|
||||
.Ltmp0:
|
||||
.cv_file 2 "C:\\UnitySrc\\unity\\Runtime\\Export\\NativeArray\\NativeArray.cs"
|
||||
.cv_inline_site_id 1 within 0 inlined_at 1 58 0
|
||||
.cv_file 3 "C:\\UnitySrc\\burst\\src\\com.unity.burst\\Tests\\Editor\\BurstInspectorGUITests.cs"
|
||||
.cv_inline_site_id 2 within 1 inlined_at 3 393 0
|
||||
.cv_loc 2 2 130 0
|
||||
mov eax, dword ptr [rcx + 8]
|
||||
test rax, rax
|
||||
.Ltmp1:
|
||||
.cv_loc 1 3 393 0
|
||||
je .LBB4_1
|
||||
mov rdx, qword ptr [rcx]
|
||||
vxorps xmm0, xmm0, xmm0
|
||||
.p2align 4, 0x90
|
||||
.LBB4_3:
|
||||
.cv_loc 1 3 395 0
|
||||
vaddss xmm0, xmm0, dword ptr [rdx]
|
||||
.cv_loc 1 3 393 0
|
||||
add rdx, 4
|
||||
dec rax
|
||||
jne .LBB4_3
|
||||
jmp .LBB4_4
|
||||
.LBB4_1:
|
||||
vxorps xmm0, xmm0, xmm0
|
||||
.LBB4_4:
|
||||
.Ltmp2:
|
||||
.cv_inline_site_id 3 within 1 inlined_at 3 397 0
|
||||
.cv_loc 3 2 194 0
|
||||
mov rax, qword ptr [rcx + 48]
|
||||
vmovss dword ptr [rax], xmm0
|
||||
.Ltmp3:
|
||||
.cv_loc 0 1 59 0
|
||||
pop rbp
|
||||
ret
|
||||
.Ltmp4:
|
||||
.Lfunc_end4:
|
||||
.seh_endproc
|
||||
|
||||
.section .drectve,"yn"
|
||||
.ascii " /EXPORT:\"burst.initialize\""
|
||||
.ascii " /EXPORT:\"burst.initialize.externals\""
|
||||
.ascii " /EXPORT:\"burst.initialize.statics\""
|
||||
.ascii " /EXPORT:d675c2aa053244579b646ec09368a505"
|
||||
.section .debug$S,"dr"
|
||||
.p2align 2
|
||||
.long 4
|
||||
.long 241
|
||||
.long .Ltmp6-.Ltmp5
|
||||
.Ltmp5:
|
||||
.short .Ltmp8-.Ltmp7
|
||||
.Ltmp7:
|
||||
.short 4353
|
||||
.long 0
|
||||
.byte 0
|
||||
.p2align 2
|
||||
.Ltmp8:
|
||||
.short .Ltmp10-.Ltmp9
|
||||
.Ltmp9:
|
||||
.short 4412
|
||||
.long 0
|
||||
.short 208
|
||||
.short 0
|
||||
.short 0
|
||||
.short 91
|
||||
.short 0
|
||||
.short 14006
|
||||
.short 0
|
||||
.short 0
|
||||
.short 0
|
||||
.asciz "Burst 0.0.91.0 (Frontend Version : 040e20f6-d3e4-45d8-b45b-06c6d673cedb)"
|
||||
.p2align 2
|
||||
.Ltmp10:
|
||||
.Ltmp6:
|
||||
.p2align 2
|
||||
.long 246
|
||||
.long .Ltmp12-.Ltmp11
|
||||
.Ltmp11:
|
||||
.long 0
|
||||
|
||||
|
||||
.long 4112
|
||||
.cv_filechecksumoffset 3
|
||||
.long 391
|
||||
|
||||
|
||||
.long 4115
|
||||
.cv_filechecksumoffset 2
|
||||
.long 129
|
||||
|
||||
|
||||
.long 4118
|
||||
.cv_filechecksumoffset 2
|
||||
.long 192
|
||||
.Ltmp12:
|
||||
.p2align 2
|
||||
.long 241
|
||||
.long .Ltmp14-.Ltmp13
|
||||
.Ltmp13:
|
||||
.short .Ltmp16-.Ltmp15
|
||||
.Ltmp15:
|
||||
.short 4422
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long .Lfunc_end4-"Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
.long 0
|
||||
.long 0
|
||||
.long 4126
|
||||
.secrel32 "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
.secidx "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
.byte 0
|
||||
.asciz "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
.p2align 2
|
||||
.Ltmp16:
|
||||
.short .Ltmp18-.Ltmp17
|
||||
.Ltmp17:
|
||||
.short 4114
|
||||
.long 8
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.short 0
|
||||
.long 1212416
|
||||
.p2align 2
|
||||
.Ltmp18:
|
||||
.short .Ltmp20-.Ltmp19
|
||||
.Ltmp19:
|
||||
.short 4429
|
||||
.long 0
|
||||
.long 0
|
||||
.long 4112
|
||||
.cv_inline_linetable 1 3 391 .Lfunc_begin4 .Lfunc_end4
|
||||
.p2align 2
|
||||
.Ltmp20:
|
||||
.short .Ltmp22-.Ltmp21
|
||||
.Ltmp21:
|
||||
.short 4429
|
||||
.long 0
|
||||
.long 0
|
||||
.long 4115
|
||||
.cv_inline_linetable 2 2 129 .Lfunc_begin4 .Lfunc_end4
|
||||
.p2align 2
|
||||
.Ltmp22:
|
||||
.short 2
|
||||
.short 4430
|
||||
.short .Ltmp24-.Ltmp23
|
||||
.Ltmp23:
|
||||
.short 4429
|
||||
.long 0
|
||||
.long 0
|
||||
.long 4118
|
||||
.cv_inline_linetable 3 2 192 .Lfunc_begin4 .Lfunc_end4
|
||||
.p2align 2
|
||||
.Ltmp24:
|
||||
.short 2
|
||||
.short 4430
|
||||
.short 2
|
||||
.short 4430
|
||||
.short 2
|
||||
.short 4431
|
||||
.Ltmp14:
|
||||
.p2align 2
|
||||
.cv_linetable 0, "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", .Lfunc_end4
|
||||
.long 241
|
||||
.long .Ltmp26-.Ltmp25
|
||||
.Ltmp25:
|
||||
.short .Ltmp28-.Ltmp27
|
||||
.Ltmp27:
|
||||
.short 4360
|
||||
.long 4099
|
||||
.asciz "BurstInspectorGUITests/MyJob"
|
||||
.p2align 2
|
||||
.Ltmp28:
|
||||
.short .Ltmp30-.Ltmp29
|
||||
.Ltmp29:
|
||||
.short 4360
|
||||
.long 4104
|
||||
.asciz "Unity.Collections.NativeArray`1<System.Single>"
|
||||
.p2align 2
|
||||
.Ltmp30:
|
||||
.short .Ltmp32-.Ltmp31
|
||||
.Ltmp31:
|
||||
.short 4360
|
||||
.long 4107
|
||||
.asciz "Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle"
|
||||
.p2align 2
|
||||
.Ltmp32:
|
||||
.short .Ltmp34-.Ltmp33
|
||||
.Ltmp33:
|
||||
.short 4360
|
||||
.long 4124
|
||||
.asciz "Unity.Jobs.LowLevel.Unsafe.JobRanges"
|
||||
.p2align 2
|
||||
.Ltmp34:
|
||||
.Ltmp26:
|
||||
.p2align 2
|
||||
.cv_filechecksums
|
||||
.cv_stringtable
|
||||
.long 241
|
||||
.long .Ltmp36-.Ltmp35
|
||||
.Ltmp35:
|
||||
.short .Ltmp38-.Ltmp37
|
||||
.Ltmp37:
|
||||
.short 4428
|
||||
.long 4130
|
||||
.p2align 2
|
||||
.Ltmp38:
|
||||
.Ltmp36:
|
||||
.p2align 2
|
||||
.section .debug$T,"dr"
|
||||
.p2align 2
|
||||
.long 4
|
||||
.short 0x32
|
||||
.short 0x1505
|
||||
.short 0x0
|
||||
.short 0x80
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x0
|
||||
.asciz "BurstInspectorGUITests/MyJob"
|
||||
.byte 241
|
||||
.short 0x46
|
||||
.short 0x1505
|
||||
.short 0x0
|
||||
.short 0x80
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x0
|
||||
.asciz "Unity.Collections.NativeArray`1<System.Single>"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x2a
|
||||
.short 0x1203
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x1001
|
||||
.short 0x0
|
||||
.asciz "Inp\303\272t"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x1001
|
||||
.short 0x30
|
||||
.asciz "Output"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x32
|
||||
.short 0x1505
|
||||
.short 0x2
|
||||
.short 0x0
|
||||
.long 0x1002
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x60
|
||||
.asciz "BurstInspectorGUITests/MyJob"
|
||||
.byte 241
|
||||
.short 0x42
|
||||
.short 0x1605
|
||||
.long 0x0
|
||||
.asciz "C:\\UnitySrc\\burst\\src\\Unity.Burst.Tester\\unknown\\unknown"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1606
|
||||
.long 0x1003
|
||||
.long 0x1004
|
||||
.long 0x0
|
||||
.short 0x4a
|
||||
.short 0x1505
|
||||
.short 0x0
|
||||
.short 0x80
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x0
|
||||
.asciz "Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle"
|
||||
.byte 241
|
||||
.short 0x8a
|
||||
.short 0x1203
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x620
|
||||
.short 0x0
|
||||
.asciz "m_Buffer"
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x8
|
||||
.asciz "m_Length"
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0xc
|
||||
.asciz "m_MinIndex"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x10
|
||||
.asciz "m_MaxIndex"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x1006
|
||||
.short 0x18
|
||||
.asciz "m_Safety"
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x28
|
||||
.asciz "m_AllocatorLabel"
|
||||
.byte 241
|
||||
.short 0x46
|
||||
.short 0x1505
|
||||
.short 0x6
|
||||
.short 0x0
|
||||
.long 0x1007
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x30
|
||||
.asciz "Unity.Collections.NativeArray`1<System.Single>"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1606
|
||||
.long 0x1008
|
||||
.long 0x1004
|
||||
.long 0x0
|
||||
.short 0x4a
|
||||
.short 0x1203
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x620
|
||||
.short 0x0
|
||||
.asciz "versionNode"
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x8
|
||||
.asciz "version"
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0xc
|
||||
.asciz "staticSafetyId"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x4a
|
||||
.short 0x1505
|
||||
.short 0x3
|
||||
.short 0x0
|
||||
.long 0x100a
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x10
|
||||
.asciz "Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle"
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1606
|
||||
.long 0x100b
|
||||
.long 0x1004
|
||||
.long 0x0
|
||||
.short 0xa
|
||||
.short 0x1002
|
||||
.long 0x1000
|
||||
.long 0x1000c
|
||||
.short 0x6
|
||||
.short 0x1201
|
||||
.long 0x0
|
||||
.short 0x1a
|
||||
.short 0x1009
|
||||
.long 0x3
|
||||
.long 0x1000
|
||||
.long 0x100d
|
||||
.byte 0x0
|
||||
.byte 0x0
|
||||
.short 0x0
|
||||
.long 0x100e
|
||||
.long 0x0
|
||||
.short 0x32
|
||||
.short 0x1602
|
||||
.long 0x1000
|
||||
.long 0x100f
|
||||
.asciz "BurstInspectorGUITests.MyJob.Execute"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0xa
|
||||
.short 0x1002
|
||||
.long 0x1001
|
||||
.long 0x1000c
|
||||
.short 0x1a
|
||||
.short 0x1009
|
||||
.long 0x74
|
||||
.long 0x1001
|
||||
.long 0x1011
|
||||
.byte 0x0
|
||||
.byte 0x0
|
||||
.short 0x0
|
||||
.long 0x100e
|
||||
.long 0x0
|
||||
.short 0x3e
|
||||
.short 0x1602
|
||||
.long 0x1001
|
||||
.long 0x1012
|
||||
.asciz "Unity.Collections.NativeArray`1<float>.get_Length"
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1201
|
||||
.long 0x2
|
||||
.long 0x74
|
||||
.long 0x40
|
||||
.short 0x1a
|
||||
.short 0x1009
|
||||
.long 0x3
|
||||
.long 0x1001
|
||||
.long 0x1011
|
||||
.byte 0x0
|
||||
.byte 0x0
|
||||
.short 0x2
|
||||
.long 0x1014
|
||||
.long 0x0
|
||||
.short 0x3a
|
||||
.short 0x1602
|
||||
.long 0x1001
|
||||
.long 0x1015
|
||||
.asciz "Unity.Collections.NativeArray`1<float>.set_Item"
|
||||
.short 0x3a
|
||||
.short 0x1505
|
||||
.short 0x0
|
||||
.short 0x80
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x0
|
||||
.asciz "Unity.Jobs.LowLevel.Unsafe.JobRanges"
|
||||
.byte 241
|
||||
.short 0xa
|
||||
.short 0x1002
|
||||
.long 0x1017
|
||||
.long 0x1000c
|
||||
.short 0x1a
|
||||
.short 0x1201
|
||||
.long 0x5
|
||||
.long 0x100d
|
||||
.long 0x620
|
||||
.long 0x620
|
||||
.long 0x1018
|
||||
.long 0x74
|
||||
.short 0xe
|
||||
.short 0x1008
|
||||
.long 0x3
|
||||
.byte 0x0
|
||||
.byte 0x0
|
||||
.short 0x5
|
||||
.long 0x1019
|
||||
.short 0x62
|
||||
.short 0x1203
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x0
|
||||
.asciz "BatchSize"
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x4
|
||||
.asciz "NumJobs"
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x74
|
||||
.short 0x8
|
||||
.asciz "TotalIterationCount"
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x150d
|
||||
.short 0x3
|
||||
.long 0x620
|
||||
.short 0x10
|
||||
.asciz "StartEndIndex"
|
||||
.short 0x3a
|
||||
.short 0x1505
|
||||
.short 0x4
|
||||
.short 0x0
|
||||
.long 0x101b
|
||||
.long 0x0
|
||||
.long 0x0
|
||||
.short 0x18
|
||||
.asciz "Unity.Jobs.LowLevel.Unsafe.JobRanges"
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1606
|
||||
.long 0x101c
|
||||
.long 0x1004
|
||||
.long 0x0
|
||||
.short 0x17a
|
||||
.short 0x1601
|
||||
.long 0x0
|
||||
.long 0x101a
|
||||
.asciz "Unity.Jobs.IJobExtensions.JobStruct`1<BurstInspectorGUITests.MyJob>.Execute(ref BurstInspectorGUITests.MyJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) -> void_930e313844f708dd8e72e0cb41431524 from UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
.byte 241
|
||||
.short 0x3a
|
||||
.short 0x1605
|
||||
.long 0x0
|
||||
.asciz "C:\\UnitySrc\\burst\\src\\Unity.Burst.Tester\\unknown"
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0xe
|
||||
.short 0x1605
|
||||
.long 0x0
|
||||
.asciz "unknown"
|
||||
.short 0xa
|
||||
.short 0x1605
|
||||
.long 0x0
|
||||
.byte 0
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
.short 0x1a
|
||||
.short 0x1603
|
||||
.short 0x5
|
||||
.long 0x101f
|
||||
.long 0x0
|
||||
.long 0x1020
|
||||
.long 0x1021
|
||||
.long 0x0
|
||||
.byte 242
|
||||
.byte 241
|
||||
.globl _fltused
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e98313e850883648a977ddbceaaca946
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue