improve Class Replacement, also the class in method signatures was replaced

This commit is contained in:
Volker Berlin 2020-04-04 11:18:25 +02:00
parent 65a1f3ff76
commit 561dc37540
4 changed files with 16 additions and 8 deletions

View File

@ -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<MethodInfo> 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 );
}
}

View File

@ -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;
}
}

View File

@ -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;" )

View File

@ -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<String, StructType> structTypes = new LinkedHashMap<>();