Skip to content

Commit

Permalink
Fix workspace mapper failing in the presence of ConstantDynamic values
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Oct 27, 2024
1 parent 5e6d3ba commit 521748d
Showing 1 changed file with 34 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package software.coley.recaf.services.mapping;

import jakarta.annotation.Nonnull;
import org.objectweb.asm.ConstantDynamic;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Type;
import software.coley.recaf.info.ClassInfo;
Expand All @@ -26,11 +27,36 @@ public class WorkspaceBackedRemapper extends BasicMappingsRemapper {
* Mappings wrapper to pull values from.
*/
public WorkspaceBackedRemapper(@Nonnull Workspace workspace,
@Nonnull Mappings mappings) {
@Nonnull Mappings mappings) {
super(mappings);
this.workspace = workspace;
}

@Override
public Object mapValue(Object value) {
// We need to adapt the invoke-dynamic mapping call from the base implementation of ASM's remapper.
// This is copied from the base implementation but adds the BSM + remapped args to the call so
// that it points to our enhanced 'mapInvokeDynamicMethodName' method.
if (value instanceof ConstantDynamic constantDynamic) {
int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArgumentCount];
for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
remappedBootstrapMethodArguments[i] =
mapValue(constantDynamic.getBootstrapMethodArgument(i));
}

String descriptor = constantDynamic.getDescriptor();
return new ConstantDynamic(
mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor, constantDynamic.getBootstrapMethod(), remappedBootstrapMethodArguments),
mapDesc(descriptor),
(Handle) mapValue(constantDynamic.getBootstrapMethod()),
remappedBootstrapMethodArguments);
}

// Other values can be handled by the base implementation
return super.mapValue(value);
}

@Override
public String mapAnnotationAttributeName(String descriptor, String name) {
String annotationName = Type.getType(descriptor).getInternalName();
Expand Down Expand Up @@ -70,8 +96,9 @@ public String mapInvokeDynamicMethodName(String name, String descriptor) {
* The arguments to the bsm.
*
* @return New name of the method.
*/ @Nonnull
public String mapInvokeDynamicMethodName( @Nonnull String name, @Nonnull String descriptor, @Nonnull Handle bsm, @Nonnull Object[] bsmArguments) {
*/
@Nonnull
public String mapInvokeDynamicMethodName(@Nonnull String name, @Nonnull String descriptor, @Nonnull Handle bsm, @Nonnull Object[] bsmArguments) {
if (bsm.equals(Handles.META_FACTORY)) {
// Get the interface from the descriptor return type.
String interfaceOwner = Type.getReturnType(descriptor).getInternalName();
Expand Down Expand Up @@ -102,9 +129,10 @@ public String mapInvokeDynamicMethodName( @Nonnull String name, @Nonnull String
* Index of the variable.
*
* @return Mapped name of the variable, or the existing name if no mapping exists.
*/ @Nonnull
public String mapVariableName( @Nonnull String className , @Nonnull String methodName, @Nonnull String methodDesc,
String name, String desc, int index) {
*/
@Nonnull
public String mapVariableName(@Nonnull String className, @Nonnull String methodName, @Nonnull String methodDesc,
String name, String desc, int index) {
String mapped = mappings.getMappedVariableName(className, methodName, methodDesc, name, desc, index);
if (mapped != null) {
markModified();
Expand Down

0 comments on commit 521748d

Please sign in to comment.