Initial commit: AIGame Unity client with URP, HybridCLR, YooAsset and tooling.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Lets the EditMode test assembly use internal test helpers (PipelineClient, AttachByPathFixture, ...)
|
||||
// now that this assembly's test types are internal rather than public (PVP-200-1).
|
||||
[assembly: InternalsVisibleTo("Unity.Pipeline.Tests.Editor")]
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe7b2493e2d763e4e8d35332e1be7717
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// CLI-224 fixture: an already-compiled MonoBehaviour used to exercise attach_script's --script
|
||||
/// (asset path) addressing — the command resolves the backing class from the .cs asset via
|
||||
/// MonoScript.GetClass(), so an agent can pass the create_script assetPath directly.
|
||||
///
|
||||
/// It deliberately lives in the RUNTIME test assembly (Unity.Pipeline.Tests.Runtime, all-platforms),
|
||||
/// NOT the editor test assembly: Unity refuses AddComponent for a MonoBehaviour whose dedicated
|
||||
/// MonoScript belongs to an editor-only assembly, so a real attach must target a runtime script —
|
||||
/// which also matches how agents author scripts under Assets/. The class name matches the file name
|
||||
/// (Unity requires that for a single-type script to be addable).
|
||||
/// </summary>
|
||||
class AttachByPathFixture : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private int m_Value;
|
||||
|
||||
public int Value => m_Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ba2fadc593de9d4994b993941573feb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,414 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
using Unity.Pipeline.Runtime.Commands;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Integration tests for in-place code reload editing workflow.
|
||||
/// Tests the complete pipeline: source parsing -> validation -> transformation -> compilation.
|
||||
/// </summary>
|
||||
[Ignore("CodeReload in-place editing is deferred until the autonomous test loop is solid; this path exercises the known instance-to-static transformation bug. Re-enable when revisiting in-place reload.")]
|
||||
class CodeReloadInPlaceEditingTests
|
||||
{
|
||||
private string _testFilePath;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
// Clean registry before each test
|
||||
CodeReloadRegistry.ClearAllForTesting();
|
||||
|
||||
// Create temp test file path
|
||||
_testFilePath = Path.Combine(Application.temporaryCachePath, "CodeReloadExampleComponent.cs");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// Clean up test file
|
||||
if (File.Exists(_testFilePath))
|
||||
{
|
||||
File.Delete(_testFilePath);
|
||||
}
|
||||
|
||||
// Clean registry after test
|
||||
CodeReloadRegistry.ClearAllForTesting();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator InPlaceReload_ValidPublicMemberAccess_ShouldSucceed()
|
||||
{
|
||||
// Arrange: Create source file with [CodeReload] method using only public members
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float speed = 5.0f;
|
||||
public bool isActive = true;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
transform.position += Vector3.right * speed * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(task.Result.Success, $"In-place reload should succeed. Error: {task.Result.ErrorMessage}");
|
||||
Assert.AreEqual("CodeReloadExampleComponent", task.Result.OriginalTypeName);
|
||||
Assert.Contains("Update", task.Result.ExtractedMethods);
|
||||
Assert.IsTrue(task.Result.RegisteredMethods.Count > 0, "Should have registered at least one method");
|
||||
Assert.IsNotNull(task.Result.TransformedCode, "Should have generated transformed code");
|
||||
|
||||
// Verify registry state
|
||||
var stats = CodeReloadRegistry.GetStats();
|
||||
Assert.IsTrue(stats.ActiveOverrideCount > 0, "Should have active overrides registered");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator InPlaceReload_PrivateMemberAccess_FailsValidationOnCompiledBackend()
|
||||
{
|
||||
// The compiled (Assembly.Load) backend cannot reach non-public members at runtime — Mono
|
||||
// JIT-enforces accessibility on the loaded override IL — so the reload is rejected up
|
||||
// front by AccessibilityValidator. The interpreter backend supports private access (see
|
||||
// IlInterpreterCodeReloadInterpreterTests).
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
private float privateSpeed = 5.0f;
|
||||
public bool isActive = true;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
transform.position += Vector3.right * privateSpeed * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
Assert.IsFalse(task.Result.Success,
|
||||
"In-place reload on the compiled backend should fail validation for private member access");
|
||||
StringAssert.Contains("privateSpeed", task.Result.ErrorMessage,
|
||||
"The validation error should name the offending member");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator InPlaceReload_MultipleCodeReloadableMethods_ShouldSucceed()
|
||||
{
|
||||
// Arrange: Create source file with multiple [CodeReload] methods
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
using Unity.Pipeline.Samples.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float speed = 5.0f;
|
||||
public int health = 100;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
transform.position += Vector3.right * speed * Time.deltaTime;
|
||||
}
|
||||
|
||||
[CodeReload]
|
||||
public int CalculateDamage(int baseDamage)
|
||||
{
|
||||
return baseDamage * 2;
|
||||
}
|
||||
|
||||
[CodeReload]
|
||||
public void ResetPosition()
|
||||
{
|
||||
transform.position = Vector3.zero;
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(task.Result.Success, $"In-place reload should succeed. Error: {task.Result.ErrorMessage}");
|
||||
Assert.AreEqual(3, task.Result.ExtractedMethods.Count, "Should extract 3 [CodeReload] methods");
|
||||
Assert.Contains("Update", task.Result.ExtractedMethods);
|
||||
Assert.Contains("CalculateDamage", task.Result.ExtractedMethods);
|
||||
Assert.Contains("ResetPosition", task.Result.ExtractedMethods);
|
||||
|
||||
// Verify transformed code contains all methods
|
||||
Assert.IsTrue(task.Result.TransformedCode.Contains("[CodeReloadOverrideMethod(\"CodeReloadExampleComponent.Update\")]"));
|
||||
Assert.IsTrue(task.Result.TransformedCode.Contains("[CodeReloadOverrideMethod(\"CodeReloadExampleComponent.CalculateDamage\")]"));
|
||||
Assert.IsTrue(task.Result.TransformedCode.Contains("[CodeReloadOverrideMethod(\"CodeReloadExampleComponent.ResetPosition\")]"));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ReloadFileCommand_InPlaceSourceFile_ShouldUseInPlaceWorkflow()
|
||||
{
|
||||
// Arrange: Create source file with [CodeReload] method
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float speed = 5.0f;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
transform.position += Vector3.up * speed * Time.deltaTime;
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute reload_file command
|
||||
var response = CodeReloadCommands.ReloadFile(_testFilePath);
|
||||
|
||||
// Assert
|
||||
yield return null; // Allow frame to complete
|
||||
|
||||
Assert.IsTrue(response.Success, $"reload_file command should succeed. Error: {response.ErrorDetails}");
|
||||
Assert.IsNotNull(response.AssemblyName, "Should have assembly name");
|
||||
Assert.IsTrue(response.Items.Count > 0, "Should have registered methods");
|
||||
|
||||
// Verify registry state
|
||||
var stats = CodeReloadRegistry.GetStats();
|
||||
Assert.IsTrue(stats.ActiveOverrideCount > 0, "Should have active overrides registered");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator AccessibilityValidation_MixedAccess_FlagsOnlyNonPublic()
|
||||
{
|
||||
// The compiled backend rejects non-public access up front (Mono JIT-enforces
|
||||
// accessibility at dispatch); the violation must name only the private member.
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float publicSpeed = 5.0f;
|
||||
private float privateSpeed = 3.0f;
|
||||
internal int internalHealth = 100;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
transform.position += Vector3.right * publicSpeed * Time.deltaTime;
|
||||
transform.position += Vector3.up * privateSpeed * Time.deltaTime;
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
Assert.IsFalse(task.Result.Success,
|
||||
"Mixed access should fail validation on the compiled backend (private member touched)");
|
||||
StringAssert.Contains("privateSpeed", task.Result.ErrorMessage,
|
||||
"The validation error should name the private member");
|
||||
StringAssert.DoesNotContain("publicSpeed", task.Result.ErrorMessage,
|
||||
"Public member access must not be flagged");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TransformedCode_ThisReferences_ShouldBeConvertedToInstance()
|
||||
{
|
||||
// Arrange: Create source with 'this.' references
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float speed = 5.0f;
|
||||
|
||||
[CodeReload]
|
||||
void Update()
|
||||
{
|
||||
this.transform.position += Vector3.right * this.speed * Time.deltaTime;
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(task.Result.Success, $"Should succeed. Error: {task.Result.ErrorMessage}");
|
||||
|
||||
var transformedCode = task.Result.TransformedCode;
|
||||
Assert.IsNotNull(transformedCode, "Should have transformed code");
|
||||
|
||||
// Verify 'this.' is converted to 'instance.'
|
||||
Assert.IsFalse(transformedCode.Contains("this."), "Transformed code should not contain 'this.' references");
|
||||
Assert.IsTrue(transformedCode.Contains("instance."), "Transformed code should contain 'instance.' references");
|
||||
Assert.IsTrue(transformedCode.Contains("instance.transform"), "Should convert this.transform to instance.transform");
|
||||
Assert.IsTrue(transformedCode.Contains("instance.speed"), "Should convert this.speed to instance.speed");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator MethodSignatures_WithParameters_ShouldPreserveParameterInfo()
|
||||
{
|
||||
// Arrange: Create source with parameterized [CodeReload] method
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class CodeReloadExampleComponent : MonoBehaviour
|
||||
{
|
||||
public float speed = 5.0f;
|
||||
|
||||
[CodeReload]
|
||||
public void MoveTowards(Vector3 target, float customSpeed)
|
||||
{
|
||||
var direction = (target - transform.position).normalized;
|
||||
transform.position += direction * customSpeed * Time.deltaTime;
|
||||
}
|
||||
}";
|
||||
|
||||
File.WriteAllText(_testFilePath, sourceCode);
|
||||
|
||||
// Act: Execute in-place reload command
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
return await InPlaceReloadProcessor.ProcessSourceFileAsync(_testFilePath);
|
||||
});
|
||||
|
||||
yield return new WaitUntil(() => task.IsCompleted);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(task.Result.Success, $"Should succeed. Error: {task.Result.ErrorMessage}");
|
||||
|
||||
var transformedCode = task.Result.TransformedCode;
|
||||
Assert.IsNotNull(transformedCode, "Should have transformed code");
|
||||
|
||||
// Verify method signature includes instance parameter plus original parameters
|
||||
Assert.IsTrue(transformedCode.Contains("MoveTowards(CodeReloadExampleComponent instance, Vector3 target, float customSpeed)"),
|
||||
$"Should preserve method parameters with instance parameter first. Actual:\n{transformedCode}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContainsCodeReloadableMethods_ValidFile_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
using Unity.Pipeline.CodeReload;
|
||||
|
||||
public class TestComponent : MonoBehaviour
|
||||
{
|
||||
[CodeReload]
|
||||
void Update() { }
|
||||
}";
|
||||
|
||||
var testPath = Path.Combine(Application.temporaryCachePath, "TestCheck.cs");
|
||||
File.WriteAllText(testPath, sourceCode);
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
var result = InPlaceReloadProcessor.ContainsCodeReloadableMethodsAsync(testPath).GetAwaiter().GetResult();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "Should detect [CodeReload] methods");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(testPath))
|
||||
{
|
||||
File.Delete(testPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContainsCodeReloadableMethods_NoCodeReloadMethods_ShouldReturnFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sourceCode = @"
|
||||
using UnityEngine;
|
||||
|
||||
public class TestComponent : MonoBehaviour
|
||||
{
|
||||
void Update() { }
|
||||
}";
|
||||
|
||||
var testPath = Path.Combine(Application.temporaryCachePath, "TestCheck.cs");
|
||||
File.WriteAllText(testPath, sourceCode);
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
var result = InPlaceReloadProcessor.ContainsCodeReloadableMethodsAsync(testPath).GetAwaiter().GetResult();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "Should not detect [CodeReload] methods");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(testPath))
|
||||
{
|
||||
File.Delete(testPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2789a86fdd0d2cc4ebea1b80a5b428d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,417 @@
|
||||
// <auto-generated>
|
||||
// Pre-compiled IL probe blobs for IlInterpreterAotSmokeTests. DO NOT EDIT.
|
||||
// Generated by IlInterpreter/tests/IlInterpreter.ProbeGen (which also holds the probe SOURCES and
|
||||
// verifies every blob against a real-C# oracle and the interpreter before writing).
|
||||
// Regenerate from the repo root: dotnet run --project IlInterpreter/tests/IlInterpreter.ProbeGen
|
||||
// </auto-generated>
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
static class IlInterpreterAotProbeBlobs
|
||||
{
|
||||
public sealed class IntCase
|
||||
{
|
||||
public readonly string Name; public readonly string Base64; public readonly int Expected;
|
||||
public IntCase(string name, string base64, int expected) { Name = name; Base64 = base64; Expected = expected; }
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
|
||||
// Source:
|
||||
// public class S {
|
||||
// public static float VecSum() { var v = new UnityEngine.Vector3(1f, 2f, 3f); return v.x + v.y + v.z; }
|
||||
// public static int Add(int a, int b) { return a + b; }
|
||||
// }
|
||||
public const string HazardProbe =
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAGLB6fYAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAAuiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAGgkAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAABMJAAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAwAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcJAAAAAAAAEgAAAAC" +
|
||||
"AAUArCAAAKADAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwBAAwAAAA" +
|
||||
"AQAAEQASACIAAIA/IgAAAEAiAABAQCgFAAAKBnsGAAAKBnsHAAAKWAZ7CAAAClgLKwAHKhMwAgAJAAAAAgAAEQACA1gKKwAGKiIC" +
|
||||
"KAkAAAoAKgAAQlNKQgEAAQAAAAAADAAAAHY0LjAuMzAzMTkAAAAABQBsAAAAWAEAACN+AADEAQAAVAEAACNTdHJpbmdzAAAAABgD" +
|
||||
"AAAEAAAAI1VTABwDAAAQAAAAI0dVSUQAAAAsAwAAdAAAACNCbG9iAAAAAAAAAAIAAAFHFQIACQAAAAD6ATMAFgAAAQAAAAcAAAAC" +
|
||||
"AAAAAwAAAAIAAAAJAAAABAAAAAIAAAABAAAAAgAAAAAAvQABAAAAAAAGAH8AFQEGAJ8AFQEGAFMAAgEPADUBAAAGAGcAFQEGAEQB" +
|
||||
"1wAKAAEARwAAAAAACQAAAAAAAQABAAEAEAASAAAAGQABAAEAUCAAAAAAlgDeAC0AAQCMIAAAAACWAC0AMQABAKEgAAAAAIYY/AAG" +
|
||||
"AAMAAAABABQAAAACACsACQD8AAEAEQD8AAYAGQD8AAoAKQD8AAEAOQD8ABYAOQBLAR0AOQBNAR0AOQBPAR0AMQD8AAYAJwAjAGgA" +
|
||||
"LgALADcALgATAEAALgAbAF8AEAAgAASAAAAAAAAAAAAAAAAAAAAAADEAAAAKAAAAAAAAAAAAAAAkABYAAAAAAAEAAAAAAAAAAAAA" +
|
||||
"AAAA5QAAAAAAAAAAVmVjdG9yMwA8TW9kdWxlPgBTAGEAU3lzdGVtLlByaXZhdGUuQ29yZUxpYgBBZGQASWxJbnRlcnByZXRlckFv" +
|
||||
"dFByb2JlAFVuaXR5RW5naW5lAERlYnVnZ2FibGVBdHRyaWJ1dGUAUmVmU2FmZXR5UnVsZXNBdHRyaWJ1dGUAQ29tcGlsYXRpb25S" +
|
||||
"ZWxheGF0aW9uc0F0dHJpYnV0ZQBSdW50aW1lQ29tcGF0aWJpbGl0eUF0dHJpYnV0ZQBJbEludGVycHJldGVyQW90UHJvYmUuZGxs" +
|
||||
"AFN5c3RlbQBWZWNTdW0ASWxJbnRlcnByZXRlci5Qcm9iZUdlbgAuY3RvcgBTeXN0ZW0uRGlhZ25vc3RpY3MAU3lzdGVtLlJ1bnRp" +
|
||||
"bWUuQ29tcGlsZXJTZXJ2aWNlcwBEZWJ1Z2dpbmdNb2RlcwBPYmplY3QAeAB5AHoAAAAAAAAAAENQDeZ/OKtAhI/MlU2CifwABCAB" +
|
||||
"AQgDIAABBSABARERBQcCER0MBiADAQwMDAIGDAMHAQgIfOyF176neY4DAAAMBQACCAgICAEACAAAAAAAHgEAAQBUAhZXcmFwTm9u" +
|
||||
"RXhjZXB0aW9uVGhyb3dzAQgBAAcBAAAAAAgBAAsAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAACQJAAAAAAAAAAA" +
|
||||
"AACqJAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnCQAAAAAAAAAAAAAAABfQ29yRGxsTWFpbgBtc2NvcmVlLmRsbAAAAAAA/yUA" +
|
||||
"IAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAALw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==";
|
||||
|
||||
public static readonly IntCase[] IntCorpus =
|
||||
{
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int a=3; int b=4; return a*b + 2 - 1; } }
|
||||
new IntCase("MulAddSub",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECADoKZ48AAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAA/iMAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAKwjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAACQIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAABAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgIwAAAAAAAEgAAAAC" +
|
||||
"AAUAeCAAABgDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAgARAAAA" +
|
||||
"AQAAEQAZChoLBgdaGFgXWQwrAAgqIgIoBQAACgAqAABCU0pCAQABAAAAAAAMAAAAdjQuMC4zMDMxOQAAAAAFAGwAAAAIAQAAI34A" +
|
||||
"AHQBAAAwAQAAI1N0cmluZ3MAAAAApAIAAAQAAAAjVVMAqAIAABAAAAAjR1VJRAAAALgCAABgAAAAI0Jsb2IAAAAAAAAAAgAAAUcU" +
|
||||
"AgAJAAAAAPoBMwAWAAABAAAABgAAAAIAAAACAAAABQAAAAQAAAABAAAAAQAAAAEAAAAAAKsAAQAAAAAABgBtAPMABgCNAPMABgBB" +
|
||||
"AOAADwATAQAABgBVAPMABgAiAc8AAAAAAAEAAAAAAAEAAQABABAAKQEAABkAAQABAFAgAAAAAJYA1gAfAAEAbSAAAAAAhhjaAAYA" +
|
||||
"AQAJANoAAQARANoABgAZANoACgApANoAAQAxANoABgAnACMAVAAuAAsAIwAuABMALAAuABsASwAQAASAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"ACEAAAAKAAAAAAAAAAAAAAAWAAoAAAAAAAAAAAAAPE1vZHVsZT4AU3lzdGVtLlByaXZhdGUuQ29yZUxpYgBJbEludGVycHJldGVy" +
|
||||
"QW90UHJvYmVfTXVsQWRkU3ViAERlYnVnZ2FibGVBdHRyaWJ1dGUAUmVmU2FmZXR5UnVsZXNBdHRyaWJ1dGUAQ29tcGlsYXRpb25S" +
|
||||
"ZWxheGF0aW9uc0F0dHJpYnV0ZQBSdW50aW1lQ29tcGF0aWJpbGl0eUF0dHJpYnV0ZQBJbEludGVycHJldGVyQW90UHJvYmVfTXVs" +
|
||||
"QWRkU3ViLmRsbABTeXN0ZW0AUnVuAC5jdG9yAFN5c3RlbS5EaWFnbm9zdGljcwBTeXN0ZW0uUnVudGltZS5Db21waWxlclNlcnZp" +
|
||||
"Y2VzAERlYnVnZ2luZ01vZGVzAE9iamVjdABTY3JpcHQAAAAAAAkCWsPhnxdMgoayNVXKnkkABCABAQgDIAABBSABARERBQcDCAgI" +
|
||||
"CHzshde+p3mOAwAACAgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEIAQAHAQAAAAAIAQALAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA1CMAAAAAAAAAAAAA7iMAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAjAAAAAAAA" +
|
||||
"AAAAAAAAX0NvckRsbE1haW4AbXNjb3JlZS5kbGwAAAAAAP8lACAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
13),
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int s=0; for (int i=0;i<10;i++) s+=i*i; return s; } }
|
||||
new IntCase("ForLoopSquares",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAJ+9QcMAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAAGiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAMgjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAACsIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAIAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8IwAAAAAAAEgAAAAC" +
|
||||
"AAUAiCAAACQDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAwAgAAAA" +
|
||||
"AQAAEQAWChYLKwoGBwdaWAoHF1gLBx8K/gQMCC3tBg0rAAkqIgIoBQAACgAqAAAAQlNKQgEAAQAAAAAADAAAAHY0LjAuMzAzMTkA" +
|
||||
"AAAABQBsAAAACAEAACN+AAB0AQAAPAEAACNTdHJpbmdzAAAAALACAAAEAAAAI1VTALQCAAAQAAAAI0dVSUQAAADEAgAAYAAAACNC" +
|
||||
"bG9iAAAAAAAAAAIAAAFHFAIACQAAAAD6ATMAFgAAAQAAAAYAAAACAAAAAgAAAAUAAAAEAAAAAQAAAAEAAAABAAAAAACLAAEAAAAA" +
|
||||
"AAYATQDYAAYAbQDYAAYAIQDFAA8A+AAAAAYANQDYAAYALAG0AAAAAAABAAAAAAABAAEAAQAQADMBAAAZAAEAAQBQIAAAAACWALsA" +
|
||||
"IAABAHwgAAAAAIYYvwAGAAEACQC/AAEAEQC/AAYAGQC/AAoAKQC/AAEAMQC/AAYAJwAjAFUALgALACQALgATAC0ALgAbAEwAEAAE" +
|
||||
"gAAAAAAAAAAAAAAAAAAAAAAHAQAACgAAAAAAAAAAAAAAFwAKAAAAAAAAAAAAADxNb2R1bGU+AFN5c3RlbS5Qcml2YXRlLkNvcmVM" +
|
||||
"aWIARGVidWdnYWJsZUF0dHJpYnV0ZQBSZWZTYWZldHlSdWxlc0F0dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmli" +
|
||||
"dXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAElsSW50ZXJwcmV0ZXJBb3RQcm9iZV9Gb3JMb29wU3F1YXJlcy5kbGwA" +
|
||||
"U3lzdGVtAFJ1bgAuY3RvcgBTeXN0ZW0uRGlhZ25vc3RpY3MAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBEZWJ1Z2dp" +
|
||||
"bmdNb2RlcwBJbEludGVycHJldGVyQW90UHJvYmVfRm9yTG9vcFNxdWFyZXMAT2JqZWN0AFNjcmlwdAAAAAAAAAAPKdSMYZMaR77Z" +
|
||||
"+VyekBkWAAQgAQEIAyAAAQUgAQEREQYHBAgIAggIfOyF176neY4DAAAICAEACAAAAAAAHgEAAQBUAhZXcmFwTm9uRXhjZXB0aW9u" +
|
||||
"VGhyb3dzAQgBAAcBAAAAAAgBAAsAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAPAjAAAAAAAAAAAAAAokAAAAIAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAD8IwAAAAAAAAAAAAAAAF9Db3JEbGxNYWluAG1zY29yZWUuZGxsAAAAAAD/JQAgABAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAABw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
285),
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int s=0; int i=0; do { s+=i; i++; } while (i<10); return s; } }
|
||||
new IntCase("DoWhileSum",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAMq+UqAAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAADiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAALwjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAACgIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAFAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwIwAAAAAAAEgAAAAC" +
|
||||
"AAUAhCAAABwDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAgAeAAAA" +
|
||||
"AQAAEQAWChYLAAYHWAoHF1gLAAcfCv4EDAgt7QYNKwAJKiICKAUAAAoAKgBCU0pCAQABAAAAAAAMAAAAdjQuMC4zMDMxOQAAAAAF" +
|
||||
"AGwAAAAIAQAAI34AAHQBAAA0AQAAI1N0cmluZ3MAAAAAqAIAAAQAAAAjVVMArAIAABAAAAAjR1VJRAAAALwCAABgAAAAI0Jsb2IA" +
|
||||
"AAAAAAAAAgAAAUcUAgAJAAAAAPoBMwAWAAABAAAABgAAAAIAAAACAAAABQAAAAQAAAABAAAAAQAAAAEAAAAAAIsAAQAAAAAABgBN" +
|
||||
"APUABgBtAPUABgAhAOIADwAVAQAABgA1APUABgAkAbAAAAAAAAEAAAAAAAEAAQABABAAKwEAABkAAQABAFAgAAAAAJYA2AAgAAEA" +
|
||||
"eiAAAAAAhhjcAAYAAQAJANwAAQARANwABgAZANwACgApANwAAQAxANwABgAnACMAVQAuAAsAJAAuABMALQAuABsATAAQAASAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAALcAAAAKAAAAAAAAAAAAAAAXAAoAAAAAAAAAAAAAPE1vZHVsZT4AU3lzdGVtLlByaXZhdGUuQ29yZUxpYgBE" +
|
||||
"ZWJ1Z2dhYmxlQXR0cmlidXRlAFJlZlNhZmV0eVJ1bGVzQXR0cmlidXRlAENvbXBpbGF0aW9uUmVsYXhhdGlvbnNBdHRyaWJ1dGUA" +
|
||||
"UnVudGltZUNvbXBhdGliaWxpdHlBdHRyaWJ1dGUASWxJbnRlcnByZXRlckFvdFByb2JlX0RvV2hpbGVTdW0uZGxsAFN5c3RlbQBJ" +
|
||||
"bEludGVycHJldGVyQW90UHJvYmVfRG9XaGlsZVN1bQBSdW4ALmN0b3IAU3lzdGVtLkRpYWdub3N0aWNzAFN5c3RlbS5SdW50aW1l" +
|
||||
"LkNvbXBpbGVyU2VydmljZXMARGVidWdnaW5nTW9kZXMAT2JqZWN0AFNjcmlwdAAAAAAAAAAAYgQhGzz3R7fq2siCEQvuAAQgAQEI" +
|
||||
"AyAAAQUgAQEREQYHBAgIAggIfOyF176neY4DAAAICAEACAAAAAAAHgEAAQBUAhZXcmFwTm9uRXhjZXB0aW9uVGhyb3dzAQgBAAcB" +
|
||||
"AAAAAAgBAAsAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAOQjAAAAAAAAAAAAAP4jAAAAIAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAADwIwAAAAAAAAAAAAAAAF9Db3JEbGxNYWluAG1zY29yZWUuZGxsAAAAAAD/JQAgABAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAABA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
45),
|
||||
// Source:
|
||||
// public class Script { static int Fib(int n){ if(n<2) return n; return Fib(n-1)+Fib(n-2); } public static int Run(){ return Fib(15); } }
|
||||
new IntCase("Fib15",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAMqXIbgAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAARiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAPQjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAADYIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAATAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoJAAAAAAAAEgAAAAC" +
|
||||
"AAUApCAAADQDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAwAjAAAA" +
|
||||
"AQAAEQACGP4ECgYsBAILKxQCF1koAQAABgIYWSgBAAAGWAsrAAcqABMwAQANAAAAAgAAEQAfDygBAAAGCisABioiAigFAAAKACoA" +
|
||||
"AEJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAAACABAAAjfgAAjAEAACwBAAAjU3RyaW5ncwAAAAC4AgAABAAAACNV" +
|
||||
"UwC8AgAAEAAAACNHVUlEAAAAzAIAAGgAAAAjQmxvYgAAAAAAAAACAAABRxUCAAkAAAAA+gEzABYAAAEAAAAGAAAAAgAAAAMAAAAB" +
|
||||
"AAAABQAAAAQAAAACAAAAAQAAAAEAAAAAAKsAAQAAAAAABgBtAO8ABgCNAO8ABgBBANwADwAPAQAABgBVAO8ABgAeAcsAAAAAAB0A" +
|
||||
"AAAAAAEAAQABABAAJQEAABkAAQABAFAgAAAAAJEAJgAiAAEAgCAAAAAAlgDSACcAAgCZIAAAAACGGNYABgACAAAAAQDUAAkA1gAB" +
|
||||
"ABEA1gAGABkA1gAKACkA1gABADEA1gAGACcAIwBcAC4ACwArAC4AEwA0AC4AGwBTABAAFQAEgAAAAAAAAAAAAAAAAAAAAAABAAAA" +
|
||||
"CgAAAAAAAAAAAAAAGQAqAAAAAAAAAABJbEludGVycHJldGVyQW90UHJvYmVfRmliMTUAPE1vZHVsZT4ARmliAFN5c3RlbS5Qcml2" +
|
||||
"YXRlLkNvcmVMaWIARGVidWdnYWJsZUF0dHJpYnV0ZQBSZWZTYWZldHlSdWxlc0F0dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRp" +
|
||||
"b25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAElsSW50ZXJwcmV0ZXJBb3RQcm9iZV9GaWIxNS5kbGwA" +
|
||||
"U3lzdGVtAFJ1bgAuY3RvcgBTeXN0ZW0uRGlhZ25vc3RpY3MAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBEZWJ1Z2dp" +
|
||||
"bmdNb2RlcwBPYmplY3QAU2NyaXB0AAAAAACdnWdAVO7MTL2mzGTelnTSAAQgAQEIAyAAAQUgAQEREQQHAgIIAwcBCAh87IXXvqd5" +
|
||||
"jgQAAQgIAwAACAgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEIAQAHAQAAAAAIAQALAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAHCQAAAAAAAAAAAAANiQAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgkAAAAAAAAAAAA" +
|
||||
"AAAAX0NvckRsbE1haW4AbXNjb3JlZS5kbGwAAAAAAP8lACAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAEg0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
610),
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int[] a=new int[5]; for(int i=0;i<5;i++) a[i]=i*i; int s=0; for(int i=0;i<5;i++) s+=a[i]; return s; } }
|
||||
new IntCase("ArraySumSquares",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECANM5maoAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAATiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAPwjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAADgIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAVAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJAAAAAAAAEgAAAAC" +
|
||||
"AAUArCAAADQDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwBABFAAAA" +
|
||||
"AQAAEQAbjQcAAAEKFgwrCgYICAhanggXWAwIG/4EDQkt7hYLFhMEKw0HBhEElFgLEQQXWBMEEQQb/gQTBREFLegHEwYrABEGKiIC" +
|
||||
"KAUAAAoAKgAAQlNKQgEAAQAAAAAADAAAAHY0LjAuMzAzMTkAAAAABQBsAAAADAEAACN+AAB4AQAARAEAACNTdHJpbmdzAAAAALwC" +
|
||||
"AAAEAAAAI1VTAMACAAAQAAAAI0dVSUQAAADQAgAAZAAAACNCbG9iAAAAAAAAAAIAAAFHFAIACQAAAAD6ATMAFgAAAQAAAAcAAAAC" +
|
||||
"AAAAAgAAAAUAAAAEAAAAAQAAAAEAAAABAAAAAACRAAEAAAAAAAYAUwDfAAYAcwDfAAYAJwDMAA8A/wAAAAYAOwDfAAYANAG7AAYA" +
|
||||
"AQC7AAAAAAAHAAAAAAABAAEAAQAQADsBAAAZAAEAAQBQIAAAAACWAMIAJAABAKEgAAAAAIYYxgAGAAEACQDGAAEAEQDGAAYAGQDG" +
|
||||
"AAoAKQDGAAEAMQDGAAYAJwAjAFkALgALACgALgATADEALgAbAFAAEAAEgAAAAAAAAAAAAAAAAAAAAAAOAQAACgAAAAAAAAAAAAAA" +
|
||||
"GwAQAAAAAAAAAABJbnQzMgA8TW9kdWxlPgBTeXN0ZW0uUHJpdmF0ZS5Db3JlTGliAERlYnVnZ2FibGVBdHRyaWJ1dGUAUmVmU2Fm" +
|
||||
"ZXR5UnVsZXNBdHRyaWJ1dGUAQ29tcGlsYXRpb25SZWxheGF0aW9uc0F0dHJpYnV0ZQBSdW50aW1lQ29tcGF0aWJpbGl0eUF0dHJp" +
|
||||
"YnV0ZQBJbEludGVycHJldGVyQW90UHJvYmVfQXJyYXlTdW1TcXVhcmVzLmRsbABTeXN0ZW0AUnVuAC5jdG9yAFN5c3RlbS5EaWFn" +
|
||||
"bm9zdGljcwBTeXN0ZW0uUnVudGltZS5Db21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAElsSW50ZXJwcmV0ZXJBb3RQcm9i" +
|
||||
"ZV9BcnJheVN1bVNxdWFyZXMAT2JqZWN0AFNjcmlwdAAAAAAAAABIr0vVZgaWTqrTZsBwrEMwAAQgAQEIAyAAAQUgAQEREQoHBx0I" +
|
||||
"CAgCCAIICHzshde+p3mOAwAACAgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEIAQAHAQAAAAAIAQALAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAkJAAAAAAAAAAAAAA+JAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCQA" +
|
||||
"AAAAAAAAAAAAAABfQ29yRGxsTWFpbgBtc2NvcmVlLmRsbAAAAAAA/yUAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAFA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
30),
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int i=300; return (byte)i; } }
|
||||
new IntCase("ByteTruncation",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAMpIrdMAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAAAiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAALAjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAACUIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAACAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkIwAAAAAAAEgAAAAC" +
|
||||
"AAUAdCAAACADAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAQAOAAAA" +
|
||||
"AQAAEQAgLAEAAAoG0gsrAAcqIgIoBQAACgAqAEJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAAAAgBAAAjfgAAdAEA" +
|
||||
"ADwBAAAjU3RyaW5ncwAAAACwAgAABAAAACNVUwC0AgAAEAAAACNHVUlEAAAAxAIAAFwAAAAjQmxvYgAAAAAAAAACAAABRxQCAAkA" +
|
||||
"AAAA+gEzABYAAAEAAAAGAAAAAgAAAAIAAAAFAAAABAAAAAEAAAABAAAAAQAAAAAAiwABAAAAAAAGAE0A/QAGAG0A/QAGACEA6gAP" +
|
||||
"AB0BAAAGADUA/QAGACwBtAAAAAAAAQAAAAAAAQABAAEAEAAzAQAAGQABAAEAUCAAAAAAlgDgAB4AAQBqIAAAAACGGOQABgABAAkA" +
|
||||
"5AABABEA5AAGABkA5AAKACkA5AABADEA5AAGACcAIwBTAC4ACwAiAC4AEwArAC4AGwBKABAABIAAAAAAAAAAAAAAAAAAAAAAuwAA" +
|
||||
"AAoAAAAAAAAAAAAAABUACgAAAAAAAAAAAAA8TW9kdWxlPgBTeXN0ZW0uUHJpdmF0ZS5Db3JlTGliAERlYnVnZ2FibGVBdHRyaWJ1" +
|
||||
"dGUAUmVmU2FmZXR5UnVsZXNBdHRyaWJ1dGUAQ29tcGlsYXRpb25SZWxheGF0aW9uc0F0dHJpYnV0ZQBSdW50aW1lQ29tcGF0aWJp" +
|
||||
"bGl0eUF0dHJpYnV0ZQBJbEludGVycHJldGVyQW90UHJvYmVfQnl0ZVRydW5jYXRpb24uZGxsAFN5c3RlbQBJbEludGVycHJldGVy" +
|
||||
"QW90UHJvYmVfQnl0ZVRydW5jYXRpb24AUnVuAC5jdG9yAFN5c3RlbS5EaWFnbm9zdGljcwBTeXN0ZW0uUnVudGltZS5Db21waWxl" +
|
||||
"clNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAE9iamVjdABTY3JpcHQAAAAAAAAAx+hHWFz2A0qYMkkHB+GlzwAEIAEBCAMgAAEFIAEB" +
|
||||
"EREEBwIICAh87IXXvqd5jgMAAAgIAQAIAAAAAAAeAQABAFQCFldyYXBOb25FeGNlcHRpb25UaHJvd3MBCAEABwEAAAAACAEACwAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAANgjAAAAAAAAAAAAAPIjAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkIwAA" +
|
||||
"AAAAAAAAAAAAAF9Db3JEbGxNYWluAG1zY29yZWUuZGxsAAAAAAD/JQAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAAQ0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
44),
|
||||
// Source:
|
||||
// public class Script { public static int Run() { int r=0; for(int i=0;i<6;i++){ switch(i){ case 0: r+=1; break; case 1: r+=10; break; default: r+=100; break; } } return r; } }
|
||||
new IntCase("SwitchInLoop",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECADFhC58AAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAANiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAOQjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAADIIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAPAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYJAAAAAAAAEgAAAAC" +
|
||||
"AAUAqCAAACADAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAgBCAAAA" +
|
||||
"AQAAEQAWChYLKykABw0JDAgsCCsACBcuCCsNBhdYCisOBh8KWAorBwYfZFgKKwAABxdYCwcc/gQTBBEELc0GEwUrABEFKiICKAUA" +
|
||||
"AAoAKgBCU0pCAQABAAAAAAAMAAAAdjQuMC4zMDMxOQAAAAAFAGwAAAAIAQAAI34AAHQBAAA4AQAAI1N0cmluZ3MAAAAArAIAAAQA" +
|
||||
"AAAjVVMAsAIAABAAAAAjR1VJRAAAAMACAABgAAAAI0Jsb2IAAAAAAAAAAgAAAUcUAgAJAAAAAPoBMwAWAAABAAAABgAAAAIAAAAC" +
|
||||
"AAAABQAAAAQAAAABAAAAAQAAAAEAAAAAAIsAAQAAAAAABgBNAPkABgBtAPkABgAhAOYADwAZAQAABgA1APkABgAoAbIAAAAAAAEA" +
|
||||
"AAAAAAEAAQABABAALwEAABkAAQABAFAgAAAAAJYAuQAiAAEAniAAAAAAhhjgAAYAAQAJAOAAAQARAOAABgAZAOAACgApAOAAAQAx" +
|
||||
"AOAABgAnACMAVwAuAAsAJgAuABMALwAuABsATgAQAASAAAAAAAAAAAAAAAAAAAAAAL0AAAAKAAAAAAAAAAAAAAAZAAoAAAAAAAAA" +
|
||||
"AAAAPE1vZHVsZT4AU3lzdGVtLlByaXZhdGUuQ29yZUxpYgBEZWJ1Z2dhYmxlQXR0cmlidXRlAFJlZlNhZmV0eVJ1bGVzQXR0cmli" +
|
||||
"dXRlAENvbXBpbGF0aW9uUmVsYXhhdGlvbnNBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRyaWJ1dGUASWxJbnRlcnBy" +
|
||||
"ZXRlckFvdFByb2JlX1N3aXRjaEluTG9vcC5kbGwAU3lzdGVtAFJ1bgBJbEludGVycHJldGVyQW90UHJvYmVfU3dpdGNoSW5Mb29w" +
|
||||
"AC5jdG9yAFN5c3RlbS5EaWFnbm9zdGljcwBTeXN0ZW0uUnVudGltZS5Db21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAE9i" +
|
||||
"amVjdABTY3JpcHQAAAAAAAAA/3BsCFGZd0a4dd7oUWB13wAEIAEBCAMgAAEFIAEBEREIBwYICAgIAggIfOyF176neY4DAAAICAEA" +
|
||||
"CAAAAAAAHgEAAQBUAhZXcmFwTm9uRXhjZXB0aW9uVGhyb3dzAQgBAAcBAAAAAAgBAAsAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAMJAAAAAAAAAAAAAAmJAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGCQAAAAAAAAAAAAAAABfQ29yRGxsTWFpbgBt" +
|
||||
"c2NvcmVlLmRsbAAAAAAA/yUAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAADg0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
411),
|
||||
// Source:
|
||||
// public struct P { public int x; public int y; } public class Script { public static int Run() { P p=new P(); p.x=3; p.y=4; return p.x*p.x + p.y*p.y; } }
|
||||
new IntCase("ScriptStructFields",
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAN89tq0AAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAAbiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAABwkAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAAAAJAAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAdAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQJAAAAAAAAEgAAAAC" +
|
||||
"AAUAoCAAAGADAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAwA5AAAA" +
|
||||
"AQAAEQASAP4VAgAAAhIAGX0BAAAEEgAafQIAAAQGewEAAAQGewEAAARaBnsCAAAEBnsCAAAEWlgLKwAHKiICKAUAAAoAKgAAQlNK" +
|
||||
"QgEAAQAAAAAADAAAAHY0LjAuMzAzMTkAAAAABQBsAAAALAEAACN+AACYAQAAVAEAACNTdHJpbmdzAAAAAOwCAAAEAAAAI1VTAPAC" +
|
||||
"AAAQAAAAI0dVSUQAAAAAAwAAYAAAACNCbG9iAAAAAAAAAAIAAAFXFAIACQAAAAD6ATMAFgAAAQAAAAcAAAADAAAAAgAAAAIAAAAF" +
|
||||
"AAAABAAAAAEAAAABAAAAAQAAAAAAlwABAAAAAAAGAFkAEQEGAHkAEQEGAC0A1QAPADEBAAAGAEEAEQEGACMAxAAGAEABxAAAAAAA" +
|
||||
"AQAAAAAAAQABAAkBEAAKAAAAGQABAAEAAQAQAEcBAAAdAAMAAQAGAE4BHwAGAFABHwBQIAAAAACWAMsAIgABAJUgAAAAAIYYzwAG" +
|
||||
"AAEACQDPAAEAEQDPAAYAGQDPAAoAKQDPAAEAOQDPAAYAJwAjAFcALgALACYALgATAC8ALgAbAE4AEAAEgAAAAAAAAAAAAAAAAAAA" +
|
||||
"AADoAAAACgAAAAAAAAAAAAAAFgAMAAAAAAAAAAAAADxNb2R1bGU+AFAAU3lzdGVtLlByaXZhdGUuQ29yZUxpYgBWYWx1ZVR5cGUA" +
|
||||
"RGVidWdnYWJsZUF0dHJpYnV0ZQBSZWZTYWZldHlSdWxlc0F0dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRl" +
|
||||
"AFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAElsSW50ZXJwcmV0ZXJBb3RQcm9iZV9TY3JpcHRTdHJ1Y3RGaWVsZHMuZGxs" +
|
||||
"AFN5c3RlbQBSdW4ALmN0b3IAU3lzdGVtLkRpYWdub3N0aWNzAElsSW50ZXJwcmV0ZXJBb3RQcm9iZV9TY3JpcHRTdHJ1Y3RGaWVs" +
|
||||
"ZHMAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBEZWJ1Z2dpbmdNb2RlcwBPYmplY3QAU2NyaXB0AHgAeQAAAAAAAACZ" +
|
||||
"+mzkMb73RJhQpUCEHnJaAAQgAQEIAyAAAQUgAQEREQUHAhEICAh87IXXvqd5jgIGCAMAAAgIAQAIAAAAAAAeAQABAFQCFldyYXBO" +
|
||||
"b25FeGNlcHRpb25UaHJvd3MBCAEABwEAAAAACAEACwAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAEQkAAAAAAAAAAAA" +
|
||||
"AF4kAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQJAAAAAAAAAAAAAAAAF9Db3JEbGxNYWluAG1zY29yZWUuZGxsAAAAAAD/JQAg" +
|
||||
"ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAHA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==",
|
||||
25),
|
||||
};
|
||||
|
||||
// Source:
|
||||
// public class Script { public static float Run() { float a=1.5f; float b=2.0f; return a*b + 0.5f; } }
|
||||
// Expected: 3.5f
|
||||
public const string FloatProbe =
|
||||
"TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgB" +
|
||||
"TM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAECAHB6NakAAAAAAAAAAOAA" +
|
||||
"IiALATAAAAYAAAACAAAAAAAACiQAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAABgAAAAAgAAAAAAAAMAQIUA" +
|
||||
"ABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAALgjAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAwAAACcIwAA" +
|
||||
"HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAA" +
|
||||
"AC50ZXh0AAAAEAQAAAAgAAAABgAAAAIAAAAAAAAAAAAAAAAAACAAAGAucmVsb2MAAAwAAAAAQAAAAAIAAAAIAAAAAAAAAAAAAAAA" +
|
||||
"AABAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsIwAAAAAAAEgAAAAC" +
|
||||
"AAUAgCAAABwDAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwAgAbAAAA" +
|
||||
"AQAAEQAiAADAPwoiAAAAQAsGB1oiAAAAP1gMKwAIKiICKAUAAAoAKkJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAA" +
|
||||
"AAgBAAAjfgAAdAEAADQBAAAjU3RyaW5ncwAAAACoAgAABAAAACNVUwCsAgAAEAAAACNHVUlEAAAAvAIAAGAAAAAjQmxvYgAAAAAA" +
|
||||
"AAACAAABRxQCAAkAAAAA+gEzABYAAAEAAAAGAAAAAgAAAAIAAAAFAAAABAAAAAEAAAABAAAAAQAAAAAArQABAAAAAAAGAG8A9wAG" +
|
||||
"AI8A9wAGAEMA5AAPABcBAAAGAFcA9wAGACYB0wAAAAAAAQAAAAAAAQABAAEAEAAtAQAAGQABAAEAUCAAAAAAlgDaAB8AAQB3IAAA" +
|
||||
"AACGGN4ABgABAAkA3gABABEA3gAGABkA3gAKACkA3gABADEA3gAGACcAIwBUAC4ACwAjAC4AEwAsAC4AGwBLABAABIAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAIQAAAAoAAAAAAAAAAAAAABYACgAAAAAAAAAAAAA8TW9kdWxlPgBTeXN0ZW0uUHJpdmF0ZS5Db3JlTGliAElsSW50" +
|
||||
"ZXJwcmV0ZXJBb3RQcm9iZV9GbG9hdE11bEFkZABEZWJ1Z2dhYmxlQXR0cmlidXRlAFJlZlNhZmV0eVJ1bGVzQXR0cmlidXRlAENv" +
|
||||
"bXBpbGF0aW9uUmVsYXhhdGlvbnNBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRyaWJ1dGUASWxJbnRlcnByZXRlckFv" +
|
||||
"dFByb2JlX0Zsb2F0TXVsQWRkLmRsbABTeXN0ZW0AUnVuAC5jdG9yAFN5c3RlbS5EaWFnbm9zdGljcwBTeXN0ZW0uUnVudGltZS5D" +
|
||||
"b21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAE9iamVjdABTY3JpcHQAAAAAAMnqQxbevJhKsbAu7+ZacrgABCABAQgDIAAB" +
|
||||
"BSABARERBQcDDAwMCHzshde+p3mOAwAADAgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEIAQAHAQAAAAAI" +
|
||||
"AQALAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA4CMAAAAAAAAAAAAA+iMAAAAgAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAOwjAAAAAAAAAAAAAAAAX0NvckRsbE1haW4AbXNjb3JlZS5kbGwAAAAAAP8lACAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAAAw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAA==";
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7a7a7741b494313b809722bf6f0a8fe
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Unity.Pipeline.Compilation;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Compact smoke test targeting the interpreter's AOT-hazard surface. In the editor / a Mono
|
||||
/// player it passes trivially; its <b>purpose is to fail loudly when run in an IL2CPP standalone
|
||||
/// player</b> if an AOT regression (linker stripping, <c>MakeGenericMethod</c>, generic virtual
|
||||
/// dispatch, or the <c>AllowTypeStruct<T></c> boxed-struct fast path) creeps in.
|
||||
///
|
||||
/// The probe scripts are pre-compiled on desktop and embedded as IL blobs
|
||||
/// (<see cref="IlInterpreterAotProbeBlobs"/>, generated by IlInterpreter/tests/IlInterpreter.ProbeGen) —
|
||||
/// Roslyn cannot compile inside an IL2CPP player (proven by CI job 73639037), and the faithful
|
||||
/// push_reload scenario ships compiled bytes anyway; the interpreter itself needs no Roslyn.
|
||||
///
|
||||
/// Categorised "Il2Cpp" so the CI player-build job can target it (see .yamato/il2cpp-playmode.yml).
|
||||
/// </summary>
|
||||
[Category("Il2Cpp")]
|
||||
class IlInterpreterAotSmokeTests
|
||||
{
|
||||
static IlInterpreter.Interpreter.ScriptInterpreter Load(string base64)
|
||||
{
|
||||
// CreateStandard registers AllowTypeStruct<Vector3>() — the boxed-struct fast path that
|
||||
// is the primary IL2CPP hazard this test guards. It's the same builder the eval and
|
||||
// code-reload sinks run in the real player.
|
||||
var binding = IlInterpreterHostBindings.CreateStandard();
|
||||
|
||||
var interp = new IlInterpreter.Interpreter.ScriptInterpreter(binding);
|
||||
interp.Load(new RawScript(Convert.FromBase64String(base64)));
|
||||
return interp;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllowTypeStruct_Vector3_FlatFrame_RoundTrips()
|
||||
{
|
||||
using var interp = Load(IlInterpreterAotProbeBlobs.HazardProbe);
|
||||
Assert.AreEqual(6f, (float)interp.Invoke("VecSum"), 1e-4f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenericTypedInvoke_TwoArgs()
|
||||
{
|
||||
using var interp = Load(IlInterpreterAotProbeBlobs.HazardProbe);
|
||||
// Invoke<int,int> exercises the generic typed-arg path (MakeGenericMethod under IL2CPP).
|
||||
Assert.AreEqual(42, interp.Invoke<int, int>("Add", 19, 23));
|
||||
}
|
||||
|
||||
// A representative slice of the desktop differential-oracle corpus, replayed under IL2CPP.
|
||||
// Sources and expected values live in the generator, which re-verifies both (real-C# oracle
|
||||
// + interpreter) at generation time; this closes the "desktop interpreter == IL2CPP
|
||||
// interpreter" link for more than the two hazard paths above.
|
||||
static IEnumerable<TestCaseData> IntCorpusCases()
|
||||
{
|
||||
foreach (var c in IlInterpreterAotProbeBlobs.IntCorpus)
|
||||
yield return new TestCaseData(c.Base64, c.Expected).SetName(
|
||||
nameof(Corpus_Int_MatchesDesktop) + "_" + c.Name);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(IntCorpusCases))]
|
||||
public void Corpus_Int_MatchesDesktop(string base64, int expected)
|
||||
{
|
||||
using var interp = Load(base64);
|
||||
Assert.AreEqual(expected, (int)interp.Invoke("Run"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Corpus_Float_MatchesDesktop()
|
||||
{
|
||||
using var interp = Load(IlInterpreterAotProbeBlobs.FloatProbe);
|
||||
Assert.AreEqual(3.5f, (float)interp.Invoke("Run"), 1e-4f);
|
||||
}
|
||||
|
||||
sealed class RawScript : IlInterpreter.IScript
|
||||
{
|
||||
public RawScript(byte[] bytes) { Il = bytes; }
|
||||
public string Name => "IlInterpreterAotProbe";
|
||||
public ReadOnlyMemory<byte> Il { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5db6a90c742899b44a5a2206613f10a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using Unity.Pipeline.Compilation;
|
||||
using Unity.Pipeline.Config;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// PlayMode paths for the IlInterpreter interpreter: interpreter execution while the player ticks, and
|
||||
/// the <see cref="RuntimePipelineDriver"/> MonoBehaviour lifecycle alongside it. These same tests,
|
||||
/// run in an IL2CPP standalone player, are the AOT payload (see <see cref="IlInterpreterAotSmokeTests"/>).
|
||||
/// </summary>
|
||||
class IlInterpreterPlayModeTests
|
||||
{
|
||||
// Compile a statement body and run it through the interpreter directly, against the shared host
|
||||
// binding (IlInterpreterHostBindings.CreateStandard) — the IL2CPP-safe path code reload uses in the
|
||||
// player (no Assembly.Load).
|
||||
static object RunViaInterpreter(string body)
|
||||
{
|
||||
var source = $@"using UnityEngine;
|
||||
public static class Probe {{ public static object Run() {{ {body} }} }}";
|
||||
|
||||
var compile = RoslynCompilationService.Compile(new CompilationRequest
|
||||
{
|
||||
SourceCode = source,
|
||||
AssemblyName = "IlInterpreterPlayModeProbe",
|
||||
SkipLoad = true,
|
||||
});
|
||||
Assert.IsTrue(compile.Success, "probe source should compile");
|
||||
|
||||
using var interp = new IlInterpreter.Interpreter.ScriptInterpreter(IlInterpreterHostBindings.CreateStandard());
|
||||
interp.Load(new RawScript(compile.AssemblyBytes));
|
||||
return interp.Invoke("Run");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Interpreter_RunsAcrossFrames()
|
||||
{
|
||||
yield return null; // ensure we're a frame into play mode
|
||||
|
||||
var result = RunViaInterpreter("return 6 * 7;");
|
||||
|
||||
Assert.AreEqual(42, result);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Interpreter_WorksWhileManagerTicks()
|
||||
{
|
||||
var config = ScriptableObject.CreateInstance<RuntimePipelineConfig>();
|
||||
config.enableInBuilds = true;
|
||||
config.autoStart = false; // no server needed; we only need the MonoBehaviour lifecycle ticking
|
||||
|
||||
var go = new GameObject("IlInterpreterRuntimeManager");
|
||||
var driver = go.AddComponent<RuntimePipelineDriver>();
|
||||
driver.Initialize(config, null);
|
||||
go.SetActive(true);
|
||||
|
||||
// Let Awake/Start/Update run.
|
||||
yield return null;
|
||||
yield return null;
|
||||
|
||||
var result = RunViaInterpreter("var v = new Vector3(2f, 3f, 6f); return v.x + v.y + v.z;");
|
||||
|
||||
Assert.AreEqual(11f, (float)result, 1e-4f);
|
||||
|
||||
UnityEngine.Object.Destroy(go);
|
||||
}
|
||||
|
||||
/// <summary>Minimal IScript over raw Roslyn-emitted PE bytes.</summary>
|
||||
sealed class RawScript : IlInterpreter.IScript
|
||||
{
|
||||
public RawScript(byte[] bytes) { Il = bytes; }
|
||||
public string Name => "IlInterpreterPlayModeProbe";
|
||||
public ReadOnlyMemory<byte> Il { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84dcf3b2f45bb59499c785d9146ddb6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,412 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Unified client for making HTTP requests to Pipeline server in tests.
|
||||
/// Provides consistent JSON payload structure and response parsing.
|
||||
/// </summary>
|
||||
class PipelineClient : IDisposable
|
||||
{
|
||||
private readonly string m_BaseUrl;
|
||||
private readonly string m_AuthToken;
|
||||
private HttpClient m_HttpClient;
|
||||
private bool m_Disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Create a Pipeline client for the specified server.
|
||||
/// </summary>
|
||||
/// <param name="baseUrl">Base URL of the Pipeline server (e.g., "http://localhost:7900")</param>
|
||||
/// <param name="authToken">Optional authentication token</param>
|
||||
public PipelineClient(string baseUrl, string authToken = null)
|
||||
{
|
||||
m_BaseUrl = baseUrl.TrimEnd('/');
|
||||
m_AuthToken = authToken;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a client for a running server, deriving the URL (port) and auth token from it.
|
||||
/// The server must be started so its token is available.
|
||||
/// </summary>
|
||||
public PipelineClient(BasePipelineServer server)
|
||||
: this($"http://localhost:{server.Port}", server.Token)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a client for a runtime server owned by a <see cref="RuntimePipelineDriver"/>.
|
||||
/// The driver must have started its server.
|
||||
/// </summary>
|
||||
public PipelineClient(RuntimePipelineDriver driver)
|
||||
: this(driver.Server)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize HttpClient for async operations (lazy initialization).
|
||||
/// </summary>
|
||||
private HttpClient GetHttpClient()
|
||||
{
|
||||
if (m_HttpClient == null)
|
||||
{
|
||||
m_HttpClient = new HttpClient();
|
||||
if (!string.IsNullOrEmpty(m_AuthToken))
|
||||
{
|
||||
m_HttpClient.DefaultRequestHeaders.Authorization =
|
||||
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", m_AuthToken);
|
||||
}
|
||||
}
|
||||
return m_HttpClient;
|
||||
}
|
||||
|
||||
// Coroutine forms for [UnityTest]. They drive the async request by polling the Task each
|
||||
// frame (yield return null) rather than yielding a UnityWebRequest AsyncOperation: the
|
||||
// EditMode test runner does not await an AsyncOperation yielded from a nested enumerator,
|
||||
// and frame-pumping also keeps the editor/player update loop (and the server's main-thread
|
||||
// dispatcher) ticking so main-thread commands can complete.
|
||||
|
||||
/// <summary>GET an endpoint (coroutine form for [UnityTest]).</summary>
|
||||
public IEnumerator GetAsync(string endpoint, System.Action<PipelineResponse> onComplete)
|
||||
=> Await(GetAsync(endpoint), onComplete);
|
||||
|
||||
/// <summary>Get server status via /api/status endpoint (coroutine form).</summary>
|
||||
public IEnumerator GetStatusAsync(System.Action<PipelineResponse> onComplete)
|
||||
=> GetAsync("/api/status", onComplete);
|
||||
|
||||
/// <summary>Execute a command via /api/exec endpoint (coroutine form).</summary>
|
||||
public IEnumerator ExecuteCommandAsync(string command, object parameters, System.Action<PipelineResponse> onComplete)
|
||||
=> Await(ExecuteCommandAsync(command, parameters), onComplete);
|
||||
|
||||
/// <summary>Execute a code evaluation command (coroutine form).</summary>
|
||||
public IEnumerator ExecuteCodeAsync(string code, int timeout, System.Action<PipelineResponse> onComplete)
|
||||
=> Await(ExecuteCodeAsync(code, timeout), onComplete);
|
||||
|
||||
/// <summary>Post JSON to an endpoint (coroutine form).</summary>
|
||||
public IEnumerator PostJsonAsync(string endpoint, object payload, System.Action<PipelineResponse> onComplete)
|
||||
=> Await(PostJsonAsync(endpoint, payload), onComplete);
|
||||
|
||||
private static IEnumerator Await(Task<PipelineResponse> task, System.Action<PipelineResponse> onComplete)
|
||||
{
|
||||
while (!task.IsCompleted)
|
||||
yield return null;
|
||||
onComplete?.Invoke(task.Result);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ASYNC METHODS (for Editor tests using async/await)
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Get server status via /api/status endpoint (async version).
|
||||
/// </summary>
|
||||
public Task<PipelineResponse> GetStatusAsync() => GetAsync("/api/status");
|
||||
|
||||
/// <summary>
|
||||
/// GET an endpoint (async version), returning a parsed <see cref="PipelineResponse"/>.
|
||||
/// </summary>
|
||||
public async Task<PipelineResponse> GetAsync(string endpoint)
|
||||
{
|
||||
var url = $"{m_BaseUrl}{endpoint}";
|
||||
|
||||
try
|
||||
{
|
||||
var httpClient = GetHttpClient();
|
||||
var httpResponse = await httpClient.GetAsync(url);
|
||||
var content = await httpResponse.Content.ReadAsStringAsync();
|
||||
|
||||
return CreateResponseFromHttp(httpResponse, content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new PipelineResponse
|
||||
{
|
||||
IsSuccess = false,
|
||||
Error = ex.Message,
|
||||
RawResponse = ""
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute a command via /api/exec endpoint (async version).
|
||||
/// </summary>
|
||||
public async Task<PipelineResponse> ExecuteCommandAsync(string command, object parameters)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
command = command,
|
||||
parameters = parameters ?? new { }
|
||||
};
|
||||
|
||||
return await PostJsonAsync("/api/exec", payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute a code evaluation command (async version).
|
||||
/// </summary>
|
||||
public async Task<PipelineResponse> ExecuteCodeAsync(string code, int timeout)
|
||||
{
|
||||
var parameters = new
|
||||
{
|
||||
code = code,
|
||||
timeout = timeout
|
||||
};
|
||||
|
||||
return await ExecuteCommandAsync("eval", parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post JSON data to an endpoint (async version).
|
||||
/// </summary>
|
||||
public async Task<PipelineResponse> PostJsonAsync(string endpoint, object payload)
|
||||
{
|
||||
var url = $"{m_BaseUrl}{endpoint}";
|
||||
var jsonData = JsonConvert.SerializeObject(payload, Formatting.Indented);
|
||||
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
|
||||
|
||||
try
|
||||
{
|
||||
var httpClient = GetHttpClient();
|
||||
var httpResponse = await httpClient.PostAsync(url, content);
|
||||
var responseContent = await httpResponse.Content.ReadAsStringAsync();
|
||||
|
||||
return CreateResponseFromHttp(httpResponse, responseContent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new PipelineResponse
|
||||
{
|
||||
IsSuccess = false,
|
||||
Error = ex.Message,
|
||||
RawResponse = ""
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get raw HTTP response (async version).
|
||||
/// </summary>
|
||||
public async Task<HttpResponseMessage> GetHttpAsync(string endpoint)
|
||||
{
|
||||
var url = $"{m_BaseUrl}{endpoint}";
|
||||
var httpClient = GetHttpClient();
|
||||
return await httpClient.GetAsync(url);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SHARED HELPER METHODS
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Create a PipelineResponse from HttpResponseMessage.
|
||||
/// </summary>
|
||||
private PipelineResponse CreateResponseFromHttp(HttpResponseMessage httpResponse, string content)
|
||||
{
|
||||
var response = new PipelineResponse
|
||||
{
|
||||
IsSuccess = httpResponse.IsSuccessStatusCode,
|
||||
StatusCode = (int)httpResponse.StatusCode,
|
||||
Error = httpResponse.IsSuccessStatusCode ? null : httpResponse.ReasonPhrase,
|
||||
RawResponse = content ?? "",
|
||||
HttpResponse = httpResponse
|
||||
};
|
||||
|
||||
// Try to parse JSON response
|
||||
if (!string.IsNullOrEmpty(response.RawResponse))
|
||||
{
|
||||
try
|
||||
{
|
||||
response.JsonResponse = JObject.Parse(response.RawResponse);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
response.ParseError = ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of any resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!m_Disposed)
|
||||
{
|
||||
m_HttpClient?.Dispose();
|
||||
m_Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standardized response from Pipeline server.
|
||||
/// </summary>
|
||||
class PipelineResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the HTTP request succeeded.
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP status code.
|
||||
/// </summary>
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP error message (if any).
|
||||
/// </summary>
|
||||
public string Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Raw response text.
|
||||
/// </summary>
|
||||
public string RawResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parsed JSON response (null if parsing failed).
|
||||
/// </summary>
|
||||
public JObject JsonResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// JSON parsing error (if any).
|
||||
/// </summary>
|
||||
public string ParseError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Original HttpResponseMessage (for advanced scenarios with async methods).
|
||||
/// </summary>
|
||||
public HttpResponseMessage HttpResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the response has valid JSON.
|
||||
/// </summary>
|
||||
public bool HasValidJson => JsonResponse != null && string.IsNullOrEmpty(ParseError);
|
||||
|
||||
/// <summary>
|
||||
/// Get a typed response object from the JSON.
|
||||
/// </summary>
|
||||
public T GetTypedResponse<T>() where T : class
|
||||
{
|
||||
if (!HasValidJson || JsonResponse == null || !JsonResponse.ContainsKey("result"))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return JsonResponse["result"].ToObject<T>();
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a JSON property value.
|
||||
/// </summary>
|
||||
public T GetProperty<T>(string propertyName, T defaultValue = default(T))
|
||||
{
|
||||
if (!HasValidJson)
|
||||
return defaultValue;
|
||||
|
||||
var token = JsonResponse[propertyName];
|
||||
if (token == null)
|
||||
return defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
return token.ToObject<T>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the command execution was successful (different from HTTP success).
|
||||
/// </summary>
|
||||
public bool IsCommandSuccess => GetProperty("success", false);
|
||||
|
||||
/// <summary>
|
||||
/// Get command error message.
|
||||
/// </summary>
|
||||
public string CommandError => GetProperty<string>("error");
|
||||
|
||||
/// <summary>
|
||||
/// Get command error details.
|
||||
/// </summary>
|
||||
public string CommandErrorDetails => GetProperty<string>("errorDetails");
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var status = IsSuccess ? "Success" : "Failed";
|
||||
var content = HasValidJson ? "JSON" : "Raw";
|
||||
return $"{status} ({StatusCode}) - {content}: {RawResponse?.Substring(0, Math.Min(100, RawResponse.Length))}...";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for common Pipeline operations.
|
||||
/// </summary>
|
||||
static class PipelineClientExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute code evaluation and get strongly-typed response (coroutine version).
|
||||
/// </summary>
|
||||
public static IEnumerator ExecuteCodeWithResponseAsync(this PipelineClient client, string code, int timeout, System.Action<Unity.Pipeline.Models.EvalResponse> onComplete)
|
||||
{
|
||||
yield return client.ExecuteCodeAsync(code, timeout, response =>
|
||||
{
|
||||
if (response.HasValidJson)
|
||||
{
|
||||
var evalResponse = response.GetTypedResponse<Unity.Pipeline.Models.EvalResponse>();
|
||||
onComplete?.Invoke(evalResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create error response
|
||||
var errorResponse = new Unity.Pipeline.Models.EvalResponse
|
||||
{
|
||||
Success = false,
|
||||
Error = response.Error ?? "HTTP Error",
|
||||
ErrorDetails = response.RawResponse ?? "No response data"
|
||||
};
|
||||
onComplete?.Invoke(errorResponse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute code evaluation and get strongly-typed response (async version).
|
||||
/// </summary>
|
||||
public static async Task<Unity.Pipeline.Models.EvalResponse> ExecuteCodeWithResponseAsync(this PipelineClient client, string code, int timeout = 5000)
|
||||
{
|
||||
var response = await client.ExecuteCodeAsync(code, timeout);
|
||||
|
||||
if (response.HasValidJson)
|
||||
{
|
||||
var evalResponse = response.GetTypedResponse<Unity.Pipeline.Models.EvalResponse>();
|
||||
if (evalResponse != null)
|
||||
return evalResponse;
|
||||
}
|
||||
|
||||
// Create error response if parsing failed
|
||||
return new Unity.Pipeline.Models.EvalResponse
|
||||
{
|
||||
Success = false,
|
||||
Error = response.Error ?? "HTTP Error",
|
||||
ErrorDetails = response.RawResponse ?? "No response data"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e682207faf781384a843402bf94e2f44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Unity.Pipeline.Runtime.Commands;
|
||||
using Unity.Pipeline.Security;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Pipeline.Tests.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Thin PlayMode smoke suite for paths that genuinely require a running player:
|
||||
/// the autoStart lifecycle (MonoBehaviour Start) and quit (DontDestroyOnLoad, play-mode only).
|
||||
/// General command behavior is covered by the EditMode *CommandTests — this only covers
|
||||
/// play-mode-only paths and one end-to-end server check.
|
||||
/// </summary>
|
||||
class RuntimeServerPlayModeSmokeTests
|
||||
{
|
||||
[UnityTest]
|
||||
public IEnumerator AutoStart_StartsServer_AndServesRequest()
|
||||
{
|
||||
var config = ScriptableObject.CreateInstance<Unity.Pipeline.Config.RuntimePipelineConfig>();
|
||||
config.enableInBuilds = true;
|
||||
config.autoStart = true;
|
||||
|
||||
var go = new GameObject("SmokeRuntimeDriver");
|
||||
var driver = go.AddComponent<RuntimePipelineDriver>();
|
||||
driver.Initialize(config, null);
|
||||
|
||||
// Start() -> autoStart -> StartServer runs on the next frame (MonoBehaviour lifecycle), not synchronously here.
|
||||
float t = 0f;
|
||||
while (!driver.IsServerRunning && t < 5f) { t += Time.unscaledDeltaTime; yield return null; }
|
||||
Assert.IsTrue(driver.IsServerRunning, "autoStart should start the runtime server");
|
||||
|
||||
var serve = ServeStatus(driver.ActualPort, SecurityTokenManager.GetOrCreateToken());
|
||||
while (!serve.IsCompleted) yield return null;
|
||||
Assert.IsTrue(serve.Result, "runtime server should serve a runtime_status request");
|
||||
|
||||
driver.StopServer();
|
||||
Object.Destroy(go);
|
||||
Object.Destroy(config);
|
||||
}
|
||||
|
||||
static async Task<bool> ServeStatus(int port, string token)
|
||||
{
|
||||
using (var client = new PipelineClient($"http://localhost:{port}", token))
|
||||
{
|
||||
var response = await client.ExecuteCommandAsync("runtime_status", null);
|
||||
return response.IsSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Quit_SchedulesQuit()
|
||||
{
|
||||
// QuitApplication uses DontDestroyOnLoad, which is play-mode only. Application.Quit is a
|
||||
// no-op in the editor, but destroy the scheduler anyway so nothing lingers.
|
||||
var result = RuntimeApplicationCommand.QuitApplication(0);
|
||||
Assert.That(result, Does.Contain("Application quit scheduled with exit code 0"));
|
||||
|
||||
foreach (var go in PipelineUtils.FindObjectsByType<GameObject>())
|
||||
{
|
||||
if (go.name.Contains("QuitScheduler")) { Object.Destroy(go); break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 062e8d6875208134e8cf794e735c719b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "Unity.Pipeline.Tests.Runtime",
|
||||
"rootNamespace": "Unity.Pipeline.Tests.Runtime",
|
||||
"references": [
|
||||
"UnityEngine.TestRunner",
|
||||
"Unity.Pipeline",
|
||||
"Unity.Pipeline.Attributes",
|
||||
"Unity.Pipeline.IlInterpreter"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_PIPELINE_INCLUDE_PACKAGE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74fd6218aa624d8458bbde685e04b0c6
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user