Skip to content

Commit

Permalink
initial work on switching to generate bridges
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Apr 30, 2024
1 parent 7201084 commit b8313cd
Show file tree
Hide file tree
Showing 32 changed files with 509 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import io.papermc.asm.ClassProcessingContext;
import io.papermc.asm.rules.RewriteRule;
import io.papermc.asm.rules.method.MethodRewriteRule;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;

import static io.papermc.asm.util.DescriptorUtils.fromOwner;
import static io.papermc.asm.util.DescriptorUtils.toOwner;
import static io.papermc.asm.util.OpcodeUtils.isStatic;
import static io.papermc.asm.util.OpcodeUtils.staticOp;

Expand All @@ -28,11 +30,11 @@ public final class DefineClassRule implements MethodRewriteRule {
"(Ljava/lang/String;[BIILjava/security/CodeSource;)Ljava/lang/Class;"
);

private final String proxy;
private final ClassDesc proxy;
private final boolean assumeClassLoader;

private DefineClassRule(final String proxyClassName, final boolean assumeClassLoader) {
this.proxy = proxyClassName;
this.proxy = fromOwner(proxyClassName);
this.assumeClassLoader = assumeClassLoader;
}

Expand All @@ -42,38 +44,39 @@ private DefineClassRule(final String proxyClassName, final boolean assumeClassLo
@Override
public @Nullable Rewrite rewrite(
final ClassProcessingContext context,
final boolean invokeDynamic,
final boolean isInvokeDynamic,
final int opcode,
final String owner,
final ClassDesc ownerDesc,
final String name,
MethodTypeDesc descriptor,
final boolean isInterface
) {
if (!name.equals("defineClass") || isStatic(opcode, invokeDynamic)) {
final String owner = toOwner(ownerDesc);
if (!name.equals("defineClass") || isStatic(opcode, isInvokeDynamic)) {
return null;
}
if (owner.equals("java/lang/invoke/MethodHandles$Lookup") && descriptor.descriptorString().equals("([B)Ljava/lang/Class;")) {
descriptor = descriptor.insertParameterTypes(0, fromOwner("java/lang/invoke/MethodHandles$Lookup"));
new RewriteSingle(staticOp(invokeDynamic), this.proxy, name, descriptor, false);
new RewriteSingle(staticOp(isInvokeDynamic), this.proxy, name, descriptor, false, isInvokeDynamic);
}
final @Nullable String superName = context.processingClassSuperClassName();
if (superName != null) {
if (CLASS_LOADER_DESCS.contains(descriptor.descriptorString())
&& this.isClassLoader(context.classInfoProvider(), superName)
&& (owner.equals(context.processingClassName()) || this.isClassLoader(context.classInfoProvider(), owner))) {
return this.classLoaderRewrite(invokeDynamic, name, descriptor);
return this.classLoaderRewrite(isInvokeDynamic, name, descriptor);
} else if (SECURE_CLASS_LOADER_DESCS.contains(descriptor.descriptorString())
&& this.isSecureClassLoader(context.classInfoProvider(), superName)
&& (owner.equals(context.processingClassName()) || this.isSecureClassLoader(context.classInfoProvider(), owner))) {
return this.classLoaderRewrite(invokeDynamic, name, descriptor);
return this.classLoaderRewrite(isInvokeDynamic, name, descriptor);
}
}
return null;
}

private MethodRewriteRule.Rewrite classLoaderRewrite(final boolean invokeDynamic, final String name, MethodTypeDesc descriptor) {
private MethodRewriteRule.Rewrite classLoaderRewrite(final boolean isInvokeDynamic, final String name, MethodTypeDesc descriptor) {
descriptor = descriptor.insertParameterTypes(0, fromOwner("java/lang/Object"));
return new RewriteSingle(staticOp(invokeDynamic), this.proxy, name, descriptor, false);
return new RewriteSingle(staticOp(isInvokeDynamic), this.proxy, name, descriptor, false, isInvokeDynamic);
}

private boolean isSecureClassLoader(final ClassInfoProvider classInfoProvider, final String className) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ protected AbstractRewriteRuleVisitorFactory(
public ClassVisitor createVisitor(final ClassVisitor parent) {
final MutableProcessingContext context = new MutableProcessingContext();
final ClassVisitor ruleVisitor = this.rule().createVisitor(this.api, parent, context);
// context filler should be last, so it is run before all the wrapped visitors
return new ContextFillerVisitor(this.api, ruleVisitor, context);
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/io/papermc/asm/rules/OwnableRewriteRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import java.util.function.Predicate;
import org.objectweb.asm.Type;

/**
* Represents a {@link RewriteRule} that has a set
* of specific owners that it targets. The owners can be
* for a targeted method or a field.
*/
public interface OwnableRewriteRule extends RewriteRule {

Set<Class<?>> owners();
Expand Down
10 changes: 1 addition & 9 deletions src/main/java/io/papermc/asm/rules/RewriteRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ static ChainBuilder chain() {

ClassVisitor createVisitor(int api, ClassVisitor parent, ClassProcessingContext context);

default void generateMethods(final MethodGeneratorFactory methodGeneratorFactory) {
}

@FunctionalInterface
interface MethodGeneratorFactory {
interface GeneratorAdapterFactory {
GeneratorAdapter create(int access, String name, String descriptor);
}

Expand All @@ -67,11 +64,6 @@ public ClassVisitor createVisitor(final int api, final ClassVisitor parent, fina
}
return visitor;
}

@Override
public void generateMethods(final MethodGeneratorFactory methodGeneratorFactory) {
this.rules.forEach(rule -> rule.generateMethods(methodGeneratorFactory));
}
}

final class ChainBuilder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,6 @@ static ConfiguredRuleFactory.Factory combine(final ConfiguredRuleFactory.Factory

void plainStaticRewrite(Consumer<? super MethodMatcher.Builder> builderConsumer);

default void changeParamFuzzy(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamFuzzy(desc(newParamType), staticHandler, builderConsumer);
}

void changeParamFuzzy(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeParamDirect(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamDirect(desc(newParamType), staticHandler, builderConsumer);
}

void changeParamDirect(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeFuzzy(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzy(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeFuzzy(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeDirect(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirect(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeDirect(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeFuzzyWithContext(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzyWithContext(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeFuzzyWithContext(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeDirectWithContext(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirectWithContext(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeDirectWithContext(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

@FunctionalInterface
interface Factory extends Consumer<ConfiguredRuleFactory> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package io.papermc.asm.rules.builder;

import io.papermc.asm.rules.builder.matcher.MethodMatcher;
import io.papermc.asm.rules.builder.matcher.TargetedMethodMatcher;
import java.lang.constant.ClassDesc;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.function.Consumer;

Expand All @@ -20,34 +17,4 @@ public class ConfiguredRuleFactoryImpl extends RuleFactoryImpl implements Config
public void plainStaticRewrite(final Consumer<? super MethodMatcher.Builder> builderConsumer) {
this.plainStaticRewrite(this.config.delegateOwner(), builderConsumer);
}

@Override
public void changeParamFuzzy(final ClassDesc newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamFuzzy(this.config.generatedDelegateOwner(), newParamType, staticHandler, builderConsumer);
}

@Override
public void changeParamDirect(final ClassDesc newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamDirect(this.config.generatedDelegateOwner(), newParamType, staticHandler, builderConsumer);
}

@Override
public void changeReturnTypeFuzzy(final ClassDesc newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzy(this.config.generatedDelegateOwner(), newReturnType, staticHandler, builderConsumer);
}

@Override
public void changeReturnTypeDirect(final ClassDesc newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirect(this.config.generatedDelegateOwner(), newReturnType, staticHandler, builderConsumer);
}

@Override
public void changeReturnTypeFuzzyWithContext(final ClassDesc newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzyWithContext(this.config.generatedDelegateOwner(), newReturnType, staticHandler, builderConsumer);
}

@Override
public void changeReturnTypeDirectWithContext(final ClassDesc newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirectWithContext(this.config.generatedDelegateOwner(), newReturnType, staticHandler, builderConsumer);
}
}
38 changes: 19 additions & 19 deletions src/main/java/io/papermc/asm/rules/builder/RuleFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ default void changeParamToSuper(final Class<?> oldParamType, final Class<?> newP
this.changeParamToSuper(desc(oldParamType), desc(newParamType), builderConsumer);
}

void changeParamToSuper(ClassDesc oldParamType, ClassDesc newParamType, Consumer<? super MethodMatcher.Builder> builderConsumer);
void changeParamToSuper(ClassDesc legacyParamType, ClassDesc newParamType, Consumer<? super MethodMatcher.Builder> builderConsumer);

default void changeParamFuzzy(final ClassDesc newOwner, final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamFuzzy(newOwner, desc(newParamType), staticHandler, builderConsumer);
default void changeParamFuzzy(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamFuzzy(desc(newParamType), staticHandler, builderConsumer);
}

void changeParamFuzzy(ClassDesc newOwner, ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeParamFuzzy(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeParamDirect(final ClassDesc newOwner, final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamDirect(newOwner, desc(newParamType), staticHandler, builderConsumer);
default void changeParamDirect(final Class<?> newParamType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeParamDirect(desc(newParamType), staticHandler, builderConsumer);
}

void changeParamDirect(ClassDesc newOwner, ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeParamDirect(ClassDesc newParamType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeToSub(final Class<?> oldReturnType, final Class<?> newReturnType, final Consumer<? super MethodMatcher.Builder> builderConsumer) {
if (!oldReturnType.isAssignableFrom(newReturnType)) {
Expand All @@ -57,29 +57,29 @@ default void changeReturnTypeToSub(final Class<?> oldReturnType, final Class<?>

void changeReturnTypeToSub(ClassDesc oldReturnType, ClassDesc newReturnType, Consumer<? super MethodMatcher.Builder> builderConsumer);

default void changeReturnTypeFuzzy(final ClassDesc newOwner, final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzy(newOwner, desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeFuzzy(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzy(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeFuzzy(ClassDesc newOwner, ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeFuzzy(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeDirect(final ClassDesc newOwner, final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirect(newOwner, desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeDirect(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirect(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeDirect(ClassDesc newOwner, ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeDirect(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeFuzzyWithContext(final ClassDesc newOwner, final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzyWithContext(newOwner, desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeFuzzyWithContext(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeFuzzyWithContext(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeFuzzyWithContext(ClassDesc newOwner, ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeFuzzyWithContext(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

default void changeReturnTypeDirectWithContext(final ClassDesc newOwner, final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirectWithContext(newOwner, desc(newReturnType), staticHandler, builderConsumer);
default void changeReturnTypeDirectWithContext(final Class<?> newReturnType, final Method staticHandler, final Consumer<? super TargetedMethodMatcher.Builder> builderConsumer) {
this.changeReturnTypeDirectWithContext(desc(newReturnType), staticHandler, builderConsumer);
}

void changeReturnTypeDirectWithContext(ClassDesc newOwner, ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);
void changeReturnTypeDirectWithContext(ClassDesc newReturnType, Method staticHandler, Consumer<? super TargetedMethodMatcher.Builder> builderConsumer);

void renameField(String newName, Consumer<? super FieldMatcher.Builder> builderConsumer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@

public interface RuleFactoryConfiguration {

static RuleFactoryConfiguration create(final ClassDesc delegateOwner, final ClassDesc generatedDelegateOwner) {
return new RuleFactoryConfigurationImpl(delegateOwner, generatedDelegateOwner);
static RuleFactoryConfiguration create(final ClassDesc delegateOwner) {
return new RuleFactoryConfigurationImpl(delegateOwner);
}

ClassDesc delegateOwner();

ClassDesc generatedDelegateOwner();

interface Holder {

RuleFactoryConfiguration configuration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

import java.lang.constant.ClassDesc;

record RuleFactoryConfigurationImpl(ClassDesc delegateOwner, ClassDesc generatedDelegateOwner) implements RuleFactoryConfiguration {
record RuleFactoryConfigurationImpl(ClassDesc delegateOwner) implements RuleFactoryConfiguration {
}
Loading

0 comments on commit b8313cd

Please sign in to comment.