SpongePowered / Mixin

Mixin is a trait/mixin and bytecode weaving framework for Java using ASM
MIT License
1.37k stars 185 forks source link

[Feature Request] Inject goto instructuion #645

Open zly2006 opened 10 months ago

zly2006 commented 10 months ago

Can we add a new injection mode that can inject gotos?

For example, original code:

class X {
  int foo(int x) {
    if (x < 0) return -x;
    bar(x)
    return x;
  }
}

then

@Goto(method="foo", at = @At(value = "INVOKE", target = "bar...", shift = BEFORE), to = @At(value = "INVOKE", target = "bar...", shift = AFTER)
boolean condition() {
  return true; // if return true, goto the "to" target, otherwise, do nothing. This is like if statement.
}

Finally, the code is like

class X {
  int foo(int x) {
    if (x < 0) return -x;
    if (condition()) {
      // nothing
    } else {
      bar(x);
    }
    return x;
  }
}

Its definition may be like:

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Goto {
    String[] method() default {};
    Desc[] target() default {};
    Slice[] slice() default {};
    At[] at();
    At to();
    boolean remap() default true;
}

I know this may be unnecessary because @Redirect is already here, but @Redirects often cause a lot of conflicts. Many redirects just add a condition, if we provide a compatible method to do that, we can reduce conflicts. What's more, this feature can support break and continue, which is also very useful i think.