From 561dc375406399e0c0b1130f9b1ad4e00afe0379 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 4 Apr 2020 11:18:25 +0200 Subject: [PATCH] improve Class Replacement, also the class in method signatures was replaced --- src/de/inetsoftware/classparser/ClassFile.java | 13 +++++++++---- src/de/inetsoftware/classparser/MethodInfo.java | 7 +++++-- .../jwebassembly/module/ReplacementForClass.java | 2 +- .../jwebassembly/module/TypeManager.java | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/de/inetsoftware/classparser/ClassFile.java b/src/de/inetsoftware/classparser/ClassFile.java index 1a8f406..6c34999 100644 --- a/src/de/inetsoftware/classparser/ClassFile.java +++ b/src/de/inetsoftware/classparser/ClassFile.java @@ -140,10 +140,11 @@ public class ClassFile { methods = classFile.methods; attributes = classFile.attributes; + String origClassName = classFile.thisClass.getName(); patchConstantPool( classFile.thisClass.getName(), thisClass ); for( MethodInfo m : methods ) { - m.setDeclaringClassFile( this ); + m.setDeclaringClassFile( origClassName, this ); } } @@ -156,6 +157,8 @@ public class ClassFile { * the reference of the class that should be used. */ private void patchConstantPool( String origClassName, ConstantClass thisClass ) { + String origSignature = 'L' + origClassName + ';'; + String thisSignature = 'L' + thisClass.getName() + ';'; // patch constant pool for( int i = 0; i < constantPool.size(); i++ ) { Object obj = constantPool.get( i ); @@ -166,7 +169,8 @@ public class ClassFile { } else if( obj instanceof ConstantRef ) { ConstantRef ref = (ConstantRef)obj; if( ref.getClassName().equals( origClassName ) ) { - ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), ref.getType() ); + String type = ref.getType().replace( origSignature, thisSignature ); + ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), type ); constantPool.set( i, new ConstantFieldRef( thisClass, nameAndType ) ); } } @@ -357,10 +361,11 @@ public class ClassFile { * extension of the class */ public void partial( ClassFile partialClassFile ) { + String origClassName = partialClassFile.thisClass.getName(); ArrayList allMethods = new ArrayList<>( Arrays.asList( methods ) ); for( MethodInfo m : partialClassFile.methods ) { if( getMethod( m.getName(), m.getType() ) == null ) { - m.setDeclaringClassFile( this ); + m.setDeclaringClassFile( origClassName, this ); allMethods.add( m ); } } @@ -374,6 +379,6 @@ public class ClassFile { } fields = allFields.toArray( fields ); - partialClassFile.patchConstantPool( partialClassFile.thisClass.getName(), thisClass ); + partialClassFile.patchConstantPool( origClassName, thisClass ); } } diff --git a/src/de/inetsoftware/classparser/MethodInfo.java b/src/de/inetsoftware/classparser/MethodInfo.java index 25e2f17..e95dc50 100644 --- a/src/de/inetsoftware/classparser/MethodInfo.java +++ b/src/de/inetsoftware/classparser/MethodInfo.java @@ -35,7 +35,7 @@ public class MethodInfo implements Member { private final String name; - private final String description; + private String description; private final Attributes attributes; @@ -214,10 +214,13 @@ public class MethodInfo implements Member { /** * Replace the reference to the ClassFile * + * @param origClassName + * the class name that should be replaced. * @param classFile * the new value */ - void setDeclaringClassFile( @Nonnull ClassFile classFile ) { + void setDeclaringClassFile( @Nonnull String origClassName, @Nonnull ClassFile classFile ) { + description = description.replace( 'L' + origClassName + ';', 'L' + classFile.getThisClass().getName() + ';' ); this.classFile = classFile; } } diff --git a/src/de/inetsoftware/jwebassembly/module/ReplacementForClass.java b/src/de/inetsoftware/jwebassembly/module/ReplacementForClass.java index a4f3042..07941e2 100644 --- a/src/de/inetsoftware/jwebassembly/module/ReplacementForClass.java +++ b/src/de/inetsoftware/jwebassembly/module/ReplacementForClass.java @@ -67,7 +67,7 @@ class ReplacementForClass { + "i32.const 4 " // length of instanceof + "i32.add " // + "call $java/lang/Class.getIntFromMemory(I)I " // first entry in instanceof is ever the id of the Class self - + "call $java/lang/Class.classConstant(I)Lde/inetsoftware/jwebassembly/module/ReplacementForClass; " // + + "call $java/lang/Class.classConstant(I)Ljava/lang/Class; " // + "return " // ) @Replace( "java/lang/Object.getClass()Ljava/lang/Class;" ) diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index 0c3f844..78b4d89 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -79,7 +79,7 @@ public class TypeManager { */ private static final int VTABLE_FIRST_FUNCTION_INDEX = 3; - private static final FunctionName CLASS_CONSTANT_FUNCTION = new FunctionName( "java/lang/Class.classConstant(I)Lde/inetsoftware/jwebassembly/module/ReplacementForClass;" ); + private static final FunctionName CLASS_CONSTANT_FUNCTION = new FunctionName( "java/lang/Class.classConstant(I)Ljava/lang/Class;" ); private Map structTypes = new LinkedHashMap<>();