mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-26 07:49:28 +01:00
add a prepare phase on compiling
This commit is contained in:
parent
5450ccb2ce
commit
f2efc5aafd
@ -157,6 +157,10 @@ public class JWebAssembly {
|
|||||||
* if any conversion error occurs
|
* if any conversion error occurs
|
||||||
*/
|
*/
|
||||||
private void compile( ModuleWriter writer ) throws IOException, WasmException {
|
private void compile( ModuleWriter writer ) throws IOException, WasmException {
|
||||||
|
for( URL url : classFiles ) {
|
||||||
|
ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
|
||||||
|
writer.prepare( classFile );
|
||||||
|
}
|
||||||
for( URL url : classFiles ) {
|
for( URL url : classFiles ) {
|
||||||
ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
|
ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
|
||||||
writer.write( classFile );
|
writer.write( classFile );
|
||||||
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.annotation.Nonnegative;
|
import javax.annotation.Nonnegative;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -30,6 +31,7 @@ import de.inetsoftware.classparser.ClassFile;
|
|||||||
import de.inetsoftware.classparser.Code;
|
import de.inetsoftware.classparser.Code;
|
||||||
import de.inetsoftware.classparser.CodeInputStream;
|
import de.inetsoftware.classparser.CodeInputStream;
|
||||||
import de.inetsoftware.classparser.ConstantPool;
|
import de.inetsoftware.classparser.ConstantPool;
|
||||||
|
import de.inetsoftware.classparser.ConstantRef;
|
||||||
import de.inetsoftware.classparser.LineNumberTable;
|
import de.inetsoftware.classparser.LineNumberTable;
|
||||||
import de.inetsoftware.classparser.LocalVariableTable;
|
import de.inetsoftware.classparser.LocalVariableTable;
|
||||||
import de.inetsoftware.classparser.MethodInfo;
|
import de.inetsoftware.classparser.MethodInfo;
|
||||||
@ -51,78 +53,115 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
private String sourceFile;
|
private String sourceFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the content of the class to the
|
* Prepare the content of the class.
|
||||||
*
|
*
|
||||||
* @param classFile
|
* @param classFile
|
||||||
* the class file
|
* the class file
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
* @throws WasmException
|
* @throws WasmException
|
||||||
* if some Java code can't converted
|
* if some Java code can't converted
|
||||||
*/
|
*/
|
||||||
public void write( ClassFile classFile ) throws IOException, WasmException {
|
public void prepare( ClassFile classFile ) {
|
||||||
sourceFile = classFile.getSourceFile();
|
iterateMethods( classFile, m -> prepareMethod( m ) );
|
||||||
if( sourceFile == null ) {
|
}
|
||||||
sourceFile = classFile.getThisClass().getName();
|
|
||||||
}
|
/**
|
||||||
MethodInfo[] methods = classFile.getMethods();
|
* Write the content of the class to the writer.
|
||||||
for( MethodInfo method : methods ) {
|
*
|
||||||
Code code = method.getCode();
|
* @param classFile
|
||||||
if( method.getName().equals( "<init>" ) && method.getDescription().equals( "()V" )
|
* the class file
|
||||||
&& code.isSuperInitReturn( classFile.getSuperClass() ) ) {
|
* @throws WasmException
|
||||||
continue; //default constructor
|
* if some Java code can't converted
|
||||||
|
*/
|
||||||
|
public void write( ClassFile classFile ) throws WasmException {
|
||||||
|
iterateMethods( classFile, m -> writeMethod( m ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void iterateMethods( ClassFile classFile, Consumer<MethodInfo> handler ) throws WasmException {
|
||||||
|
sourceFile = null; // clear previous value for the case an IO exception occur
|
||||||
|
try {
|
||||||
|
sourceFile = classFile.getSourceFile();
|
||||||
|
if( sourceFile == null ) {
|
||||||
|
sourceFile = classFile.getThisClass().getName();
|
||||||
}
|
}
|
||||||
writeMethod( method );
|
MethodInfo[] methods = classFile.getMethods();
|
||||||
|
for( MethodInfo method : methods ) {
|
||||||
|
Code code = method.getCode();
|
||||||
|
if( method.getName().equals( "<init>" ) && method.getDescription().equals( "()V" )
|
||||||
|
&& code.isSuperInitReturn( classFile.getSuperClass() ) ) {
|
||||||
|
continue; //default constructor
|
||||||
|
}
|
||||||
|
handler.accept( method );
|
||||||
|
}
|
||||||
|
} catch( IOException ioex ) {
|
||||||
|
throw WasmException.create( ioex, sourceFile, -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the method.
|
||||||
|
*
|
||||||
|
* @param method
|
||||||
|
* the method
|
||||||
|
* @throws WasmException
|
||||||
|
* if some Java code can't converted
|
||||||
|
*/
|
||||||
|
private void prepareMethod( MethodInfo method ) throws WasmException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the content of a method.
|
* Write the content of a method.
|
||||||
*
|
*
|
||||||
* @param method
|
* @param method
|
||||||
* the method
|
* the method
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
* @throws WasmException
|
* @throws WasmException
|
||||||
* if some Java code can't converted
|
* if some Java code can't converted
|
||||||
*/
|
*/
|
||||||
private void writeMethod( MethodInfo method ) throws IOException, WasmException {
|
private void writeMethod( MethodInfo method ) throws WasmException {
|
||||||
Code code = method.getCode();
|
try {
|
||||||
if( code != null ) { // abstract methods and interface methods does not have code
|
Code code = method.getCode();
|
||||||
String methodName = method.getName(); // TODO naming conversion rule
|
if( code != null ) { // abstract methods and interface methods does not have code
|
||||||
writeExport( methodName, method );
|
String methodName = method.getName(); // TODO naming conversion rule
|
||||||
writeMethodStart( methodName );
|
writeExport( methodName, method );
|
||||||
writeMethodSignature( method );
|
writeMethodStart( methodName );
|
||||||
locals.clear();
|
writeMethodSignature( method );
|
||||||
localTable = code.getLocalVariableTable();
|
locals.clear();
|
||||||
LineNumberTable lineNumberTable = code.getLineNumberTable();
|
localTable = code.getLocalVariableTable();
|
||||||
if( lineNumberTable != null ) {
|
LineNumberTable lineNumberTable = code.getLineNumberTable();
|
||||||
int lineNumber;
|
if( lineNumberTable != null ) {
|
||||||
for( int i = 0; i < lineNumberTable.size(); i++ ) {
|
int lineNumber;
|
||||||
lineNumber = lineNumberTable.getLineNumber( i );
|
for( int i = 0; i < lineNumberTable.size(); i++ ) {
|
||||||
int offset = lineNumberTable.getStartOffset( i );
|
lineNumber = lineNumberTable.getLineNumber( i );
|
||||||
int nextOffset =
|
int offset = lineNumberTable.getStartOffset( i );
|
||||||
i + 1 == lineNumberTable.size() ? code.getCodeSize()
|
int nextOffset =
|
||||||
: lineNumberTable.getStartOffset( i + 1 );
|
i + 1 == lineNumberTable.size() ? code.getCodeSize()
|
||||||
CodeInputStream byteCode = code.getByteCode( offset, nextOffset - offset );
|
: lineNumberTable.getStartOffset( i + 1 );
|
||||||
writeCodeChunk( byteCode, lineNumber, method.getConstantPool() );
|
CodeInputStream byteCode = code.getByteCode( offset, nextOffset - offset );
|
||||||
|
writeCodeChunk( byteCode, lineNumber, method.getConstantPool() );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CodeInputStream byteCode = code.getByteCode();
|
||||||
|
writeCodeChunk( byteCode, -1, method.getConstantPool() );
|
||||||
}
|
}
|
||||||
} else {
|
for( int i = Math.min( paramCount, locals.size() ); i > 0; i-- ) {
|
||||||
CodeInputStream byteCode = code.getByteCode();
|
locals.remove( 0 );
|
||||||
writeCodeChunk( byteCode, -1, method.getConstantPool() );
|
}
|
||||||
|
writeMethodFinish( locals );
|
||||||
}
|
}
|
||||||
for( int i = Math.min( paramCount, locals.size() ); i > 0; i-- ) {
|
} catch( IOException ioex ) {
|
||||||
locals.remove( 0 );
|
throw WasmException.create( ioex, sourceFile, -1 );
|
||||||
}
|
|
||||||
writeMethodFinish( locals );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for a Export annotation and if there write an export directive.
|
* Look for a Export annotation and if there write an export directive.
|
||||||
|
*
|
||||||
* @param methodName
|
* @param methodName
|
||||||
|
* the normalized method name
|
||||||
* @param method
|
* @param method
|
||||||
|
* the moethod
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
* if any IOException occur
|
||||||
*/
|
*/
|
||||||
private void writeExport( String methodName, MethodInfo method ) throws IOException {
|
private void writeExport( String methodName, MethodInfo method ) throws IOException {
|
||||||
Annotations annotations = method.getRuntimeInvisibleAnnotations();
|
Annotations annotations = method.getRuntimeInvisibleAnnotations();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user