mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
replace also a class with annotation
This commit is contained in:
parent
442b582dfc
commit
d103f97c04
@ -34,8 +34,6 @@ import de.inetsoftware.classparser.Attributes.AttributeInfo;
|
|||||||
*/
|
*/
|
||||||
public class ClassFile {
|
public class ClassFile {
|
||||||
|
|
||||||
private final DataInputStream input;
|
|
||||||
|
|
||||||
private final int minorVersion;
|
private final int minorVersion;
|
||||||
|
|
||||||
private final int majorVersion;
|
private final int majorVersion;
|
||||||
@ -71,7 +69,7 @@ public class ClassFile {
|
|||||||
* if this input stream reaches the end before reading the class file.
|
* if this input stream reaches the end before reading the class file.
|
||||||
*/
|
*/
|
||||||
public ClassFile( InputStream stream ) throws IOException {
|
public ClassFile( InputStream stream ) throws IOException {
|
||||||
this.input = new DataInputStream( stream );
|
DataInputStream input = new DataInputStream( stream );
|
||||||
int magic = input.readInt();
|
int magic = input.readInt();
|
||||||
if( magic != 0xCAFEBABE ) {
|
if( magic != 0xCAFEBABE ) {
|
||||||
throw new IOException( "Invalid class magic: " + Integer.toHexString( magic ) );
|
throw new IOException( "Invalid class magic: " + Integer.toHexString( magic ) );
|
||||||
@ -87,8 +85,8 @@ public class ClassFile {
|
|||||||
for( int i = 0; i < interfaces.length; i++ ) {
|
for( int i = 0; i < interfaces.length; i++ ) {
|
||||||
interfaces[i] = (ConstantClass)constantPool.get( input.readUnsignedShort() );
|
interfaces[i] = (ConstantClass)constantPool.get( input.readUnsignedShort() );
|
||||||
}
|
}
|
||||||
fields = readFields();
|
fields = readFields( input );
|
||||||
methods = readMethods();
|
methods = readMethods( input );
|
||||||
attributes = new Attributes( input, constantPool );
|
attributes = new Attributes( input, constantPool );
|
||||||
|
|
||||||
stream.close();
|
stream.close();
|
||||||
@ -117,6 +115,45 @@ public class ClassFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a replaced instance.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* the class name that should be replaced
|
||||||
|
* @param classFile
|
||||||
|
* the replacing class file data
|
||||||
|
*/
|
||||||
|
public ClassFile( String className, ClassFile classFile ) {
|
||||||
|
minorVersion = classFile.minorVersion;
|
||||||
|
majorVersion = classFile.majorVersion;
|
||||||
|
|
||||||
|
constantPool = classFile.constantPool;
|
||||||
|
accessFlags = classFile.accessFlags;
|
||||||
|
thisClass = new ConstantClass( className );
|
||||||
|
superClass = classFile.superClass;
|
||||||
|
interfaces = classFile.interfaces;
|
||||||
|
fields = classFile.fields;
|
||||||
|
methods = classFile.methods;
|
||||||
|
attributes = classFile.attributes;
|
||||||
|
|
||||||
|
// patch constant pool
|
||||||
|
String origClassName = classFile.thisClass.getName();
|
||||||
|
for( int i = 0; i < constantPool.size(); i++ ) {
|
||||||
|
Object obj = constantPool.get( i );
|
||||||
|
if( obj instanceof ConstantClass ) {
|
||||||
|
if( ((ConstantClass)obj).getName().equals( origClassName ) ) {
|
||||||
|
constantPool.set( i, thisClass );
|
||||||
|
}
|
||||||
|
} else if( obj instanceof ConstantFieldRef ) {
|
||||||
|
ConstantFieldRef ref = (ConstantFieldRef)obj;
|
||||||
|
if( ref.getClassName().equals( origClassName ) ) {
|
||||||
|
ConstantNameAndType nameAndType = new ConstantNameAndType( ref.getName(), ref.getType() );
|
||||||
|
constantPool.set( i, new ConstantFieldRef( thisClass, nameAndType ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value of SourceFile if available.
|
* Get value of SourceFile if available.
|
||||||
*
|
*
|
||||||
@ -216,7 +253,7 @@ public class ClassFile {
|
|||||||
return accessFlags;
|
return accessFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FieldInfo[] readFields() throws IOException {
|
private FieldInfo[] readFields( DataInputStream input ) throws IOException {
|
||||||
FieldInfo[] fields = new FieldInfo[input.readUnsignedShort()];
|
FieldInfo[] fields = new FieldInfo[input.readUnsignedShort()];
|
||||||
for( int i = 0; i < fields.length; i++ ) {
|
for( int i = 0; i < fields.length; i++ ) {
|
||||||
fields[i] = new FieldInfo( input, constantPool );
|
fields[i] = new FieldInfo( input, constantPool );
|
||||||
@ -224,7 +261,7 @@ public class ClassFile {
|
|||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodInfo[] readMethods() throws IOException {
|
private MethodInfo[] readMethods( DataInputStream input ) throws IOException {
|
||||||
MethodInfo[] methods = new MethodInfo[input.readUnsignedShort()];
|
MethodInfo[] methods = new MethodInfo[input.readUnsignedShort()];
|
||||||
for( int i = 0; i < methods.length; i++ ) {
|
for( int i = 0; i < methods.length; i++ ) {
|
||||||
methods[i] = new MethodInfo( input, constantPool, this );
|
methods[i] = new MethodInfo( input, constantPool, this );
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2011 - 2019 Volker Berlin (i-net software)
|
Copyright 2011 - 2020 Volker Berlin (i-net software)
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -147,4 +147,25 @@ public class ConstantPool {
|
|||||||
public Object get( int index ) {
|
public Object get( int index ) {
|
||||||
return constantPool[index];
|
return constantPool[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value in the constant pool.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* the index
|
||||||
|
* @param value
|
||||||
|
* the new value
|
||||||
|
*/
|
||||||
|
void set( int index, Object value ) {
|
||||||
|
constantPool[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of entries in the pool.
|
||||||
|
*
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
int size() {
|
||||||
|
return constantPool.length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package de.inetsoftware.jwebassembly.module;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -31,7 +32,9 @@ import de.inetsoftware.classparser.WeakValueCache;
|
|||||||
*/
|
*/
|
||||||
public class ClassFileLoader {
|
public class ClassFileLoader {
|
||||||
|
|
||||||
private final WeakValueCache<String, ClassFile> CACHE = new WeakValueCache<>();
|
private final HashMap<String, ClassFile> replace = new HashMap<>();
|
||||||
|
|
||||||
|
private final WeakValueCache<String, ClassFile> weakCache = new WeakValueCache<>();
|
||||||
|
|
||||||
private final ClassLoader loader;
|
private final ClassLoader loader;
|
||||||
|
|
||||||
@ -56,16 +59,32 @@ public class ClassFileLoader {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public ClassFile get( String className ) throws IOException {
|
public ClassFile get( String className ) throws IOException {
|
||||||
ClassFile classFile = CACHE.get( className );
|
ClassFile classFile = replace.get( className );
|
||||||
|
if( classFile != null ) {
|
||||||
|
return classFile;
|
||||||
|
}
|
||||||
|
classFile = weakCache.get( className );
|
||||||
if( classFile != null ) {
|
if( classFile != null ) {
|
||||||
return classFile;
|
return classFile;
|
||||||
}
|
}
|
||||||
InputStream stream = loader.getResourceAsStream( className + ".class" );
|
InputStream stream = loader.getResourceAsStream( className + ".class" );
|
||||||
if( stream != null ) {
|
if( stream != null ) {
|
||||||
classFile = new ClassFile( stream );
|
classFile = new ClassFile( stream );
|
||||||
CACHE.put( className, classFile );
|
weakCache.put( className, classFile );
|
||||||
}
|
}
|
||||||
return classFile;
|
return classFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the class in the cache with the given instance.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* the name of the class to replace
|
||||||
|
* @param classFile
|
||||||
|
* the replasing ClassFile
|
||||||
|
*/
|
||||||
|
public void replace( String className, ClassFile classFile ) {
|
||||||
|
classFile = new ClassFile( className, classFile );
|
||||||
|
replace.put( className, classFile );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 - 2019 Volker Berlin (i-net software)
|
* Copyright 2017 - 2020 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -158,8 +158,19 @@ public class ModuleGenerator {
|
|||||||
* the class file
|
* the class file
|
||||||
* @throws WasmException
|
* @throws WasmException
|
||||||
* if some Java code can't converted
|
* if some Java code can't converted
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
public void prepare( ClassFile classFile ) {
|
public void prepare( ClassFile classFile ) throws IOException {
|
||||||
|
// check if this class replace another class
|
||||||
|
Map<String,Object> annotationValues;
|
||||||
|
if( (annotationValues = classFile.getAnnotation( JWebAssembly.REPLACE_ANNOTATION )) != null ) {
|
||||||
|
String signatureName = (String)annotationValues.get( "value" );
|
||||||
|
if( signatureName != null ) {
|
||||||
|
classFileLoader.replace( signatureName, classFile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iterateMethods( classFile, m -> prepareMethod( m ) );
|
iterateMethods( classFile, m -> prepareMethod( m ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user