mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-22 19:06:15 +08:00
[Tools] Fix ShaderDump reflection invoke against new optional parameters (#166)
TryCompileVertexShader gained an optional scalarRegisterBufferIndex parameter (#156), and reflection Invoke does not apply C# default parameter values, so ShaderDump crashed with TargetParameterCountException. Pad trailing optional parameters with Type.Missing under BindingFlags.OptionalParamBinding so the declared defaults are used; only a new required parameter now needs a tool update, and that fails with a named error instead of a crash. Verified: all five programs behave as expected (exit 0), all eight emitted blobs pass spirv-val --target-env vulkan1.3. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -201,8 +201,8 @@ foreach (var (name, expectTranslate, words) in testPrograms)
|
||||
null,
|
||||
null)!;
|
||||
|
||||
object?[] compileArgs = [state, evaluation, null, null, 0, -1, 0];
|
||||
if ((bool)tryCompile.Invoke(null, compileArgs)!)
|
||||
var compileArgs = PadWithDefaults(tryCompile, [state, evaluation, null, null]);
|
||||
if ((bool)tryCompile.Invoke(null, BindingFlags.OptionalParamBinding, null, compileArgs, null)!)
|
||||
{
|
||||
var shader = compileArgs[2]!;
|
||||
var spirv = (byte[])shader.GetType().GetProperty("Spirv")!.GetValue(shader)!;
|
||||
@@ -216,8 +216,8 @@ foreach (var (name, expectTranslate, words) in testPrograms)
|
||||
Console.WriteLine($"[{name}] emit: FAILED ({compileArgs[3]})");
|
||||
}
|
||||
|
||||
object?[] computeArgs = [state, evaluation, 1u, 1u, 1u, null, null];
|
||||
if ((bool)tryCompileCompute.Invoke(null, computeArgs)!)
|
||||
var computeArgs = PadWithDefaults(tryCompileCompute, [state, evaluation, 1u, 1u, 1u, null, null]);
|
||||
if ((bool)tryCompileCompute.Invoke(null, BindingFlags.OptionalParamBinding, null, computeArgs, null)!)
|
||||
{
|
||||
var shader = computeArgs[5]!;
|
||||
var spirv = (byte[])shader.GetType().GetProperty("Spirv")!.GetValue(shader)!;
|
||||
@@ -237,6 +237,37 @@ Console.WriteLine(failures == 0
|
||||
: $"RESULT: {failures} unexpected outcome(s)");
|
||||
Environment.ExitCode = failures == 0 ? 0 : 1;
|
||||
|
||||
// Reflection Invoke does not apply C# default parameter values, so a newly
|
||||
// added optional parameter on a translator entry point would otherwise throw
|
||||
// TargetParameterCountException. Type.Missing + OptionalParamBinding lets the
|
||||
// runtime substitute the declared defaults; only a new *required* parameter
|
||||
// should force a tool update.
|
||||
static object?[] PadWithDefaults(MethodInfo method, object?[] arguments)
|
||||
{
|
||||
var parameters = method.GetParameters();
|
||||
if (arguments.Length > parameters.Length)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{method.DeclaringType?.Name}.{method.Name} takes fewer parameters than the tool supplies");
|
||||
}
|
||||
|
||||
var padded = new object?[parameters.Length];
|
||||
arguments.CopyTo(padded, 0);
|
||||
for (var i = arguments.Length; i < padded.Length; i++)
|
||||
{
|
||||
if (!parameters[i].IsOptional)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{method.DeclaringType?.Name}.{method.Name} gained a required parameter " +
|
||||
$"'{parameters[i].Name}' — the tool needs updating");
|
||||
}
|
||||
|
||||
padded[i] = Type.Missing;
|
||||
}
|
||||
|
||||
return padded;
|
||||
}
|
||||
|
||||
internal sealed class FakeMemory : ICpuMemory
|
||||
{
|
||||
private readonly List<(ulong Base, byte[] Data)> _regions = [];
|
||||
|
||||
Reference in New Issue
Block a user