2020import java .util .ArrayList ;
2121import java .util .List ;
2222import java .util .Map ;
23+ import java .util .function .Consumer ;
2324
2425import javax .annotation .Nonnegative ;
2526import javax .annotation .Nonnull ;
3031import de .inetsoftware .classparser .Code ;
3132import de .inetsoftware .classparser .CodeInputStream ;
3233import de .inetsoftware .classparser .ConstantPool ;
34+ import de .inetsoftware .classparser .ConstantRef ;
3335import de .inetsoftware .classparser .LineNumberTable ;
3436import de .inetsoftware .classparser .LocalVariableTable ;
3537import 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