Skip to content

Commit f2efc5a

Browse files
committed
add a prepare phase on compiling
1 parent 5450ccb commit f2efc5a

File tree

2 files changed

+87
-44
lines changed

2 files changed

+87
-44
lines changed

src/de/inetsoftware/jwebassembly/JWebAssembly.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ public void compileToBinary( OutputStream output ) throws WasmException {
157157
* if any conversion error occurs
158158
*/
159159
private void compile( ModuleWriter writer ) throws IOException, WasmException {
160+
for( URL url : classFiles ) {
161+
ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
162+
writer.prepare( classFile );
163+
}
160164
for( URL url : classFiles ) {
161165
ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) );
162166
writer.write( classFile );

src/de/inetsoftware/jwebassembly/module/ModuleWriter.java

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.ArrayList;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.function.Consumer;
2324

2425
import javax.annotation.Nonnegative;
2526
import javax.annotation.Nonnull;
@@ -30,6 +31,7 @@
3031
import de.inetsoftware.classparser.Code;
3132
import de.inetsoftware.classparser.CodeInputStream;
3233
import de.inetsoftware.classparser.ConstantPool;
34+
import de.inetsoftware.classparser.ConstantRef;
3335
import de.inetsoftware.classparser.LineNumberTable;
3436
import de.inetsoftware.classparser.LocalVariableTable;
3537
import de.inetsoftware.classparser.MethodInfo;
@@ -51,78 +53,115 @@ public abstract class ModuleWriter implements Closeable {
5153
private String sourceFile;
5254

5355
/**
54-
* Write the content of the class to the
56+
* Prepare the content of the class.
5557
*
5658
* @param classFile
5759
* the class file
58-
* @throws IOException
59-
* if any I/O error occur
6060
* @throws WasmException
6161
* if some Java code can't converted
6262
*/
63-
public void write( ClassFile classFile ) throws IOException, WasmException {
64-
sourceFile = classFile.getSourceFile();
65-
if( sourceFile == null ) {
66-
sourceFile = classFile.getThisClass().getName();
67-
}
68-
MethodInfo[] methods = classFile.getMethods();
69-
for( MethodInfo method : methods ) {
70-
Code code = method.getCode();
71-
if( method.getName().equals( "<init>" ) && method.getDescription().equals( "()V" )
72-
&& code.isSuperInitReturn( classFile.getSuperClass() ) ) {
73-
continue; //default constructor
63+
public void prepare( ClassFile classFile ) {
64+
iterateMethods( classFile, m -> prepareMethod( m ) );
65+
}
66+
67+
/**
68+
* Write the content of the class to the writer.
69+
*
70+
* @param classFile
71+
* the class file
72+
* @throws WasmException
73+
* if some Java code can't converted
74+
*/
75+
public void write( ClassFile classFile ) throws WasmException {
76+
iterateMethods( classFile, m -> writeMethod( m ) );
77+
}
78+
79+
private void iterateMethods( ClassFile classFile, Consumer<MethodInfo> handler ) throws WasmException {
80+
sourceFile = null; // clear previous value for the case an IO exception occur
81+
try {
82+
sourceFile = classFile.getSourceFile();
83+
if( sourceFile == null ) {
84+
sourceFile = classFile.getThisClass().getName();
85+
}
86+
MethodInfo[] methods = classFile.getMethods();
87+
for( MethodInfo method : methods ) {
88+
Code code = method.getCode();
89+
if( method.getName().equals( "<init>" ) && method.getDescription().equals( "()V" )
90+
&& code.isSuperInitReturn( classFile.getSuperClass() ) ) {
91+
continue; //default constructor
92+
}
93+
handler.accept( method );
7494
}
75-
writeMethod( method );
95+
} catch( IOException ioex ) {
96+
throw WasmException.create( ioex, sourceFile, -1 );
7697
}
7798
}
7899

100+
/**
101+
* Prepare the method.
102+
*
103+
* @param method
104+
* the method
105+
* @throws WasmException
106+
* if some Java code can't converted
107+
*/
108+
private void prepareMethod( MethodInfo method ) throws WasmException {
109+
110+
}
111+
79112
/**
80113
* Write the content of a method.
81114
*
82115
* @param method
83116
* the method
84-
* @throws IOException
85-
* if any I/O error occur
86117
* @throws WasmException
87118
* if some Java code can't converted
88119
*/
89-
private void writeMethod( MethodInfo method ) throws IOException, WasmException {
90-
Code code = method.getCode();
91-
if( code != null ) { // abstract methods and interface methods does not have code
92-
String methodName = method.getName(); // TODO naming conversion rule
93-
writeExport( methodName, method );
94-
writeMethodStart( methodName );
95-
writeMethodSignature( method );
96-
locals.clear();
97-
localTable = code.getLocalVariableTable();
98-
LineNumberTable lineNumberTable = code.getLineNumberTable();
99-
if( lineNumberTable != null ) {
100-
int lineNumber;
101-
for( int i = 0; i < lineNumberTable.size(); i++ ) {
102-
lineNumber = lineNumberTable.getLineNumber( i );
103-
int offset = lineNumberTable.getStartOffset( i );
104-
int nextOffset =
105-
i + 1 == lineNumberTable.size() ? code.getCodeSize()
106-
: lineNumberTable.getStartOffset( i + 1 );
107-
CodeInputStream byteCode = code.getByteCode( offset, nextOffset - offset );
108-
writeCodeChunk( byteCode, lineNumber, method.getConstantPool() );
120+
private void writeMethod( MethodInfo method ) throws WasmException {
121+
try {
122+
Code code = method.getCode();
123+
if( code != null ) { // abstract methods and interface methods does not have code
124+
String methodName = method.getName(); // TODO naming conversion rule
125+
writeExport( methodName, method );
126+
writeMethodStart( methodName );
127+
writeMethodSignature( method );
128+
locals.clear();
129+
localTable = code.getLocalVariableTable();
130+
LineNumberTable lineNumberTable = code.getLineNumberTable();
131+
if( lineNumberTable != null ) {
132+
int lineNumber;
133+
for( int i = 0; i < lineNumberTable.size(); i++ ) {
134+
lineNumber = lineNumberTable.getLineNumber( i );
135+
int offset = lineNumberTable.getStartOffset( i );
136+
int nextOffset =
137+
i + 1 == lineNumberTable.size() ? code.getCodeSize()
138+
: lineNumberTable.getStartOffset( i + 1 );
139+
CodeInputStream byteCode = code.getByteCode( offset, nextOffset - offset );
140+
writeCodeChunk( byteCode, lineNumber, method.getConstantPool() );
141+
}
142+
} else {
143+
CodeInputStream byteCode = code.getByteCode();
144+
writeCodeChunk( byteCode, -1, method.getConstantPool() );
109145
}
110-
} else {
111-
CodeInputStream byteCode = code.getByteCode();
112-
writeCodeChunk( byteCode, -1, method.getConstantPool() );
113-
}
114-
for( int i = Math.min( paramCount, locals.size() ); i > 0; i-- ) {
115-
locals.remove( 0 );
146+
for( int i = Math.min( paramCount, locals.size() ); i > 0; i-- ) {
147+
locals.remove( 0 );
148+
}
149+
writeMethodFinish( locals );
116150
}
117-
writeMethodFinish( locals );
151+
} catch( IOException ioex ) {
152+
throw WasmException.create( ioex, sourceFile, -1 );
118153
}
119154
}
120155

121156
/**
122157
* Look for a Export annotation and if there write an export directive.
158+
*
123159
* @param methodName
160+
* the normalized method name
124161
* @param method
162+
* the moethod
125163
* @throws IOException
164+
* if any IOException occur
126165
*/
127166
private void writeExport( String methodName, MethodInfo method ) throws IOException {
128167
Annotations annotations = method.getRuntimeInvisibleAnnotations();

0 commit comments

Comments
 (0)