mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
change the static ClassFile cache to an instance cache
This commit is contained in:
parent
f32a1ac067
commit
525a2f2f87
@ -34,8 +34,6 @@ import de.inetsoftware.classparser.Attributes.AttributeInfo;
|
|||||||
*/
|
*/
|
||||||
public class ClassFile {
|
public class ClassFile {
|
||||||
|
|
||||||
private static final WeakValueCache<String,ClassFile> CACHE = new WeakValueCache<>();
|
|
||||||
|
|
||||||
private final DataInputStream input;
|
private final DataInputStream input;
|
||||||
|
|
||||||
private final int minorVersion;
|
private final int minorVersion;
|
||||||
@ -64,30 +62,6 @@ public class ClassFile {
|
|||||||
|
|
||||||
private Map<String,Map<String,Object>> annotations;
|
private Map<String,Map<String,Object>> annotations;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ClassFile from cache or load it.
|
|
||||||
*
|
|
||||||
* @param className
|
|
||||||
* the class name
|
|
||||||
* @param loader
|
|
||||||
* the ClassLoader to load
|
|
||||||
* @return the ClassFile or null
|
|
||||||
* @throws IOException
|
|
||||||
* If any I/O error occur
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public static ClassFile get( String className, ClassLoader loader ) throws IOException {
|
|
||||||
ClassFile classFile = CACHE.get( className );
|
|
||||||
if( classFile != null ) {
|
|
||||||
return classFile;
|
|
||||||
}
|
|
||||||
InputStream stream = loader.getResourceAsStream( className + ".class" );
|
|
||||||
if( stream != null ) {
|
|
||||||
return new ClassFile( stream );
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a class file and create a model of the class.
|
* Load a class file and create a model of the class.
|
||||||
*
|
*
|
||||||
@ -141,7 +115,6 @@ public class ClassFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CACHE.put( thisClass.getName(), this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ public class ModuleGenerator {
|
|||||||
|
|
||||||
private final JavaScriptWriter javaScript;
|
private final JavaScriptWriter javaScript;
|
||||||
|
|
||||||
private final URLClassLoader libraries;
|
private final ClassFileLoader classFileLoader;
|
||||||
|
|
||||||
private final JavaMethodWasmCodeBuilder javaCodeBuilder;
|
private final JavaMethodWasmCodeBuilder javaCodeBuilder;
|
||||||
|
|
||||||
@ -93,12 +93,12 @@ public class ModuleGenerator {
|
|||||||
this.watParser = new WatParser();
|
this.watParser = new WatParser();
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
this.javaScript = new JavaScriptWriter( target );
|
this.javaScript = new JavaScriptWriter( target );
|
||||||
this.libraries = new URLClassLoader( libraries.toArray( new URL[libraries.size()] ) );
|
this.classFileLoader = new ClassFileLoader( new URLClassLoader( libraries.toArray( new URL[libraries.size()] ) ) );
|
||||||
WasmOptions options = writer.options;
|
WasmOptions options = writer.options;
|
||||||
types.init( options );
|
types.init( options );
|
||||||
strings.init( functions );
|
strings.init( functions );
|
||||||
javaCodeBuilder.init( types, functions, strings, options );
|
javaCodeBuilder.init( types, functions, strings, options, classFileLoader );
|
||||||
((WasmCodeBuilder)watParser).init( types, functions, strings, options );
|
((WasmCodeBuilder)watParser).init( types, functions, strings, options, classFileLoader );
|
||||||
scanLibraries( libraries );
|
scanLibraries( libraries );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ public class ModuleGenerator {
|
|||||||
FunctionName next;
|
FunctionName next;
|
||||||
NEXT:
|
NEXT:
|
||||||
while( (next = functions.nextScannLater()) != null ) {
|
while( (next = functions.nextScannLater()) != null ) {
|
||||||
ClassFile classFile = ClassFile.get( next.className, libraries );
|
ClassFile classFile = classFileLoader.get( next.className );
|
||||||
if( classFile == null ) {
|
if( classFile == null ) {
|
||||||
if( next instanceof SyntheticFunctionName ) {
|
if( next instanceof SyntheticFunctionName ) {
|
||||||
JWebAssembly.LOGGER.fine( '\t' + next.methodName + next.signature );
|
JWebAssembly.LOGGER.fine( '\t' + next.methodName + next.signature );
|
||||||
@ -213,7 +213,7 @@ public class ModuleGenerator {
|
|||||||
continue NEXT; // we have found a super method
|
continue NEXT; // we have found a super method
|
||||||
}
|
}
|
||||||
ConstantClass superClass = superClassFile.getSuperClass();
|
ConstantClass superClass = superClassFile.getSuperClass();
|
||||||
superClassFile = superClass == null ? null : ClassFile.get( superClass.getName(), libraries );
|
superClassFile = superClass == null ? null : classFileLoader.get( superClass.getName() );
|
||||||
}
|
}
|
||||||
throw new WasmException( "Missing function: " + next.signatureName, -1 );
|
throw new WasmException( "Missing function: " + next.signatureName, -1 );
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ public class ModuleGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JWebAssembly.LOGGER.fine( "scan finsih" );
|
JWebAssembly.LOGGER.fine( "scan finsih" );
|
||||||
types.prepareFinish( writer, functions, libraries );
|
types.prepareFinish( writer, functions, classFileLoader );
|
||||||
prepareFunctions(); // prepare of types can add some override methods as needed
|
prepareFunctions(); // prepare of types can add some override methods as needed
|
||||||
functions.prepareFinish();
|
functions.prepareFinish();
|
||||||
strings.prepareFinish( writer );
|
strings.prepareFinish( writer );
|
||||||
@ -304,7 +304,7 @@ public class ModuleGenerator {
|
|||||||
if( next instanceof SyntheticFunctionName ) {
|
if( next instanceof SyntheticFunctionName ) {
|
||||||
writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) );
|
writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) );
|
||||||
} else {
|
} else {
|
||||||
ClassFile classFile = ClassFile.get( next.className, libraries );
|
ClassFile classFile = classFileLoader.get( next.className );
|
||||||
if( classFile == null ) {
|
if( classFile == null ) {
|
||||||
throw new WasmException( "Missing function: " + next.signatureName, -1 );
|
throw new WasmException( "Missing function: " + next.signatureName, -1 );
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,15 +73,15 @@ public class TypeManager {
|
|||||||
* the targets for the types
|
* the targets for the types
|
||||||
* @param functions
|
* @param functions
|
||||||
* the used functions for the vtables of the types
|
* the used functions for the vtables of the types
|
||||||
* @param libraries
|
* @param classFileLoader
|
||||||
* for loading the class files if not in the cache
|
* for loading the class files
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur on loading or writing
|
* if any I/O error occur on loading or writing
|
||||||
*/
|
*/
|
||||||
void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassLoader libraries ) throws IOException {
|
void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassFileLoader classFileLoader ) throws IOException {
|
||||||
isFinish = true;
|
isFinish = true;
|
||||||
for( StructType type : structTypes.values() ) {
|
for( StructType type : structTypes.values() ) {
|
||||||
type.writeStructType( writer, functions, this, libraries );
|
type.writeStructType( writer, functions, this, classFileLoader );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,17 +195,17 @@ public class TypeManager {
|
|||||||
* the used functions for the vtables of the types
|
* the used functions for the vtables of the types
|
||||||
* @param types
|
* @param types
|
||||||
* for types of fields
|
* for types of fields
|
||||||
* @param libraries
|
* @param classFileLoader
|
||||||
* for loading the class files if not in the cache
|
* for loading the class files
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur on loading or writing
|
* if any I/O error occur on loading or writing
|
||||||
*/
|
*/
|
||||||
private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassLoader libraries ) throws IOException {
|
private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader ) throws IOException {
|
||||||
JWebAssembly.LOGGER.fine( "write type: " + name );
|
JWebAssembly.LOGGER.fine( "write type: " + name );
|
||||||
fields = new ArrayList<>();
|
fields = new ArrayList<>();
|
||||||
methods = new ArrayList<>();
|
methods = new ArrayList<>();
|
||||||
HashSet<String> allNeededFields = new HashSet<>();
|
HashSet<String> allNeededFields = new HashSet<>();
|
||||||
listStructFields( name, functions, types, libraries, allNeededFields );
|
listStructFields( name, functions, types, classFileLoader, allNeededFields );
|
||||||
code = writer.writeStructType( this );
|
code = writer.writeStructType( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,15 +218,15 @@ public class TypeManager {
|
|||||||
* the used functions for the vtables of the types
|
* the used functions for the vtables of the types
|
||||||
* @param types
|
* @param types
|
||||||
* for types of fields
|
* for types of fields
|
||||||
* @param libraries
|
* @param classFileLoader
|
||||||
* for loading the class files if not in the cache
|
* for loading the class files
|
||||||
* @param allNeededFields
|
* @param allNeededFields
|
||||||
* for recursive call list this all used fields
|
* for recursive call list this all used fields
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur on loading or writing
|
* if any I/O error occur on loading or writing
|
||||||
*/
|
*/
|
||||||
private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassLoader libraries, HashSet<String> allNeededFields ) throws IOException {
|
private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader, HashSet<String> allNeededFields ) throws IOException {
|
||||||
ClassFile classFile = ClassFile.get( className, libraries );
|
ClassFile classFile = classFileLoader.get( className );
|
||||||
if( classFile == null ) {
|
if( classFile == null ) {
|
||||||
throw new WasmException( "Missing class: " + className, -1 );
|
throw new WasmException( "Missing class: " + className, -1 );
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ public class TypeManager {
|
|||||||
ConstantClass superClass = classFile.getSuperClass();
|
ConstantClass superClass = classFile.getSuperClass();
|
||||||
if( superClass != null ) {
|
if( superClass != null ) {
|
||||||
String superClassName = superClass.getName();
|
String superClassName = superClass.getName();
|
||||||
listStructFields( superClassName, functions, types, libraries, allNeededFields );
|
listStructFields( superClassName, functions, types, classFileLoader, allNeededFields );
|
||||||
} else {
|
} else {
|
||||||
fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) );
|
fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) );
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,8 @@ public abstract class WasmCodeBuilder {
|
|||||||
|
|
||||||
private StringManager strings;
|
private StringManager strings;
|
||||||
|
|
||||||
|
private ClassFileLoader classFileLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the code builder;
|
* Initialize the code builder;
|
||||||
*
|
*
|
||||||
@ -80,12 +82,13 @@ public abstract class WasmCodeBuilder {
|
|||||||
* @param options
|
* @param options
|
||||||
* compiler properties
|
* compiler properties
|
||||||
*/
|
*/
|
||||||
void init( TypeManager types, FunctionManager functions, StringManager strings, WasmOptions options ) {
|
void init( TypeManager types, FunctionManager functions, StringManager strings, WasmOptions options, ClassFileLoader classFileLoader ) {
|
||||||
this.localVariables.init( types );
|
this.localVariables.init( types );
|
||||||
this.types = types;
|
this.types = types;
|
||||||
this.functions = functions;
|
this.functions = functions;
|
||||||
this.strings = strings;
|
this.strings = strings;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.classFileLoader = classFileLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -535,7 +538,7 @@ public abstract class WasmCodeBuilder {
|
|||||||
*/
|
*/
|
||||||
private FunctionName getNonGC( String name, int lineNumber ) {
|
private FunctionName getNonGC( String name, int lineNumber ) {
|
||||||
try {
|
try {
|
||||||
ClassFile classFile = ClassFile.get( NonGC.class.getName().replace( '.', '/' ), getClass().getClassLoader() );
|
ClassFile classFile = classFileLoader.get( NonGC.class.getName().replace( '.', '/' ) );
|
||||||
for( MethodInfo method : classFile.getMethods() ) {
|
for( MethodInfo method : classFile.getMethods() ) {
|
||||||
if( name.equals( method.getName() ) ) {
|
if( name.equals( method.getName() ) ) {
|
||||||
return new FunctionName( method );
|
return new FunctionName( method );
|
||||||
|
@ -40,7 +40,7 @@ public class WatParserTest {
|
|||||||
WasmOptions options = new WasmOptions( new HashMap<>() );
|
WasmOptions options = new WasmOptions( new HashMap<>() );
|
||||||
WatParser parser = new WatParser();
|
WatParser parser = new WatParser();
|
||||||
WasmCodeBuilder codeBuilder = parser;
|
WasmCodeBuilder codeBuilder = parser;
|
||||||
codeBuilder.init( null, null, null, options );
|
codeBuilder.init( null, null, null, options, null );
|
||||||
parser.parse( wat, null, 100 );
|
parser.parse( wat, null, 100 );
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options );
|
ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user