Mixin
Mixin copied to clipboard
@Redirect on switch statements
Let's give an example class:
class SomeClass {
public void something() {
// ...
switch (value) {
case A:
// ...
break;
case B:
case C:
b_and_c(value);
break;
}
}
I want to be able to redirect this switch statement so that I can handle it my own way, or I guess, in other words, replace it with my own functionality, however I am having trouble with that. I tried something using JUMP Injection, which didn't really work
Mixin(SomeClass.class) class MixinSomeClass {
@Redirect(method = "something", at = @At(value = "JUMP", target = "LSomeClass;something()V;", opcode = Opcodes.TABLESWITCH)) private void switch_redirect(Value value) {
switch (value) {
case A:
b_c(value); // just an example
break;
case B:
case C:
//...
}
}
As expected, the above fails, specifically because JumpInsnPoint doesn't actually support TABLESWITCH. All that being said, how can I redirect/replace this switch statement. Obviously, I could @Overwrite the whole method, but considering the size of it, it's not a very useful solution, I'd just need to shadow tons of fields and methods before I could even begin to work with it.
There isn't a particularly straightforward way to entirely jump over a switch, however it would absolutely be possible to special-case redirect of LOOKUPSWITCH and TABLESWITCH so that a redirector could return the value being used for the switch itself, allowing deliberate redirection into the default case or a specific case. In the situation that the default is not supplied, this would provide a way to short-circuit the switch.
Coercion could potentially be used for switch-on-string and switch-on-enum as well but I'd have to look into that.
I am not sure if I understood this correctly, but I am trying to replace the following:
private void call(int i) {
switch (i) {
case 65:
System.out.println(65);
}
}
With this:
private void call(int i) {
switch (i) {
case 70:
System.out.println(65);
}
}
This isn't currently possible, is it?
Correct, that would need the solution to this issue.
However, if it's really that simple (or similar complexity) then you could potentially cheat using @ModifyVariable and just modify i to have the value 65 whenever it's 70 and have some other value when it isn't.
Any resources on how to get started contributing? I have no experience with bytecode manipulation but would happily try to implement this. Maybe like a short todo overview/list or something I can follow? :)
It's not really bytecode manipulation so much as it is ASM. If you understand that, you'd likely be able to get a working solution.