-
-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support for general purpose param object[] #25
Comments
Harmony is not designed to do that out of the box. However, it is possible to create a transpiler that does exactly this by manipulating the IL code to shuffle the arguments that are on the CIL stack into an array. Doing this in plain Harmony would actually slow down things and I would consider this special interest. |
if you plan add it in future i made working implementation
in EmitCallParameter.
if (patchParam.Name == "_params")
{
Emitter.Emit(il, OpCodes.Ldc_I4, originalParameters.Length);
Emitter.Emit(il, OpCodes.Newarr, typeof(object));
for (int i = 0; i < originalParameters.Length; i++)
{
Emitter.Emit(il, OpCodes.Dup);
Emitter.Emit(il, OpCodes.Ldc_I4, i);
Emitter.Emit(il, OpCodes.Ldarg, i + 1);
Emitter.Emit(il, OpCodes.Box, originalParameters[i].ParameterType);
Emitter.Emit(il, OpCodes.Stelem_Ref);
}
continue;
} |
I have to double check all corner cases and all types of parameters but if I find a good general solution I might add it to Harmony too. The main problem for me is that it should support all types and even work with “ref” or “out” parameters. |
Why do you have this line friuns2? |
Actually: both. A static method has its arguments 0-based but an instance method has the instance as its first (hidden) argument. Also, putting arguments into an array will fail with ‘ref’ arguments so I have not implemented it yet. |
Too many corner cases that will fail. I'll close this for now. If you want to use array parameters, make your own transpiler submethod that you can pipe your instructions through and that calls one of your method with the array. |
Architecture idea:Don't promise abstract class PatchParameter {
abstract Object UntypedValue { get; set; }
abstract Type Type { get; }
}
class PatchParameter<T> : PatchParameter {
private bool _touched = false;
private bool _canSet = false;
// out parameter
PatchParameter() {
_canSet = true;
}
// ref or byvalue parameter
PatchParameter(T value, bool isRef = false) {
_touched = true;
_value = value;
_canSet = isRef;
}
T Value {
get {
return !_touched
? throw new InvalidOperationException("need to set value first")
: _value;
}
set {
if (!_canSet)
throw new InvalidOperationException("cannot set value");
_value = value;
_touched = true;
}
}
override Object UntypedValue => Value;
override Type Type => typeof(T);
bool CanGet => _touched;
bool CanSet => _canSet;
} |
Can you give me an example on how you would use that feature? |
I am building a kind of debugger for Unity. It'd be great to have a general patch that could accept the various data such as the original instance for instance methods, the class, arguments and the actual parameter values and then report this reflected information in my system. The only thing missing is a way to generically accept all parameter values. |
Maybe someone else steps in and makes this happen |
Yes, this is a great feature, which is VERY needed.
And usage:
Right now, my padawan is doing a graduation project that uses Harmony to trace methods without restarting the application. :) If this functionality will support out of the box, it will be awesome! |
I am working on an implementation that considers all edge cases. Maybe it finds its way into Harmony 2.2 |
i'm integrating harmony with jurrassic javascript runtime intepreter and i stuck at problem
for example original method is test(int a, string b)
but i would like to patch it with testPrefix(object[] o) so o[0]=a and o[1]=b
but its not possible currently in harmony
The text was updated successfully, but these errors were encountered: