Action OpCode(MethodInfo method)
{
if (method == null)
throw new ArgumentException("A method was expected.", "method");
var args = new List<Func<object>>();
foreach (var param in method.GetParameters().Reverse())
{
var paramType = param.ParameterType;
if (paramType.IsArray && paramType.GetElementType() == typeof(int))
{
args.Add(() => GetStackList(int.MaxValue));
}
else if (paramType == typeof(byte))
{
args.Add(() => (byte)Pop());
}
else if (paramType == typeof(short))
{
args.Add(() => (short)Pop());
}
else if (paramType == typeof(ushort))
{
args.Add(() => (ushort)Pop());
}
else if (paramType == typeof(int))
{
args.Add(() => Pop());
}
else
{
throw new ArgumentException("An array was expected as parameter.", "method");
}
}
var action = new Action(() =>
{
try
{
var parameterNames = method.GetParameters().Select(p => p.Name).ToArray();
var parameters = args.Select(arg => arg()).Reverse().ToArray();
this.Trace().Write(TraceSwitches.OpCodes, "Room = {1,3}, Script = {0,3}, Offset = {4,4}, Name = [{3:X2}] {2}({5})",
Slots[CurrentScript].Number,
_roomResource,
_opCodes.ContainsKey(_opCode) ? method.Name : "Unknown",
_opCode,
CurrentPos - 1,
string.Join(",", parameters.Select((p, i) => string.Format("{0}={1}", parameterNames[i], GetDebuggerDisplayFor(p)))));
method.Invoke(this, parameters);
}
catch (Exception)
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
else
{
throw;
}
}
});
return action;
}