Skip to content

Commit

Permalink
Use a single CoeInputStream pro method instead chucks pro line number
Browse files Browse the repository at this point in the history
  • Loading branch information
Horcrux7 committed Jun 3, 2018
1 parent 0c83869 commit ecd61dc
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 54 deletions.
26 changes: 4 additions & 22 deletions src/de/inetsoftware/classparser/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -128,28 +126,12 @@ public int getLastLineNr() throws IOException {
}

/**
* Get a list of CodeInputStream separated by source code line number.
* Get the stream of Java Byte code instruction of this method.
*
* @return the list
* @throws IOException
* if any I/O error occur
* @return the stream
*/
public Collection<CodeInputStream> getByteCodes() throws IOException {
ArrayList<CodeInputStream> list = new ArrayList<>();
LineNumberTable lineNumberTable = getLineNumberTable();
if( lineNumberTable != null ) {
int lineNumber;
for( int i = 0; i < lineNumberTable.size(); i++ ) {
lineNumber = lineNumberTable.getLineNumber( i );
int offset = lineNumberTable.getStartOffset( i );
int nextOffset = i + 1 == lineNumberTable.size() ? getCodeSize()
: lineNumberTable.getStartOffset( i + 1 );
list.add( new CodeInputStream( codeData, offset, nextOffset - offset, lineNumber ) );
}
} else {
list.add( new CodeInputStream( codeData, 0, codeData.length, -1 ) );
}
return list;
public CodeInputStream getByteCode() {
return new CodeInputStream( codeData, 0, codeData.length, this );
}

public int getCodeSize(){
Expand Down
27 changes: 22 additions & 5 deletions src/de/inetsoftware/classparser/CodeInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;

/**
* Extends the DataInputStream with a code position.
Expand All @@ -26,7 +27,7 @@
*/
public class CodeInputStream extends DataInputStream {

private int lineNumber;
private Code code;

/**
* Create a new instance of CodeInputStream.
Expand All @@ -37,12 +38,12 @@ public class CodeInputStream extends DataInputStream {
* the offset in the array
* @param length
* the length
* @param lineNumber
* the lineNumber in the source code or -1 if not available
* @param code
* the calling code to get the line numbers
*/
CodeInputStream( byte[] buf, int offset, int length, int lineNumber ) {
CodeInputStream( byte[] buf, int offset, int length, Code code ) {
this( new ByteCodeArrayInputStream( buf, offset, length ) );
this.lineNumber = lineNumber;
this.code = code;
}

private CodeInputStream( ByteCodeArrayInputStream in ) {
Expand All @@ -64,6 +65,22 @@ public int getCodePosition() {
* @return the line number
*/
public int getLineNumber() {
int lineNumber = -1;
try {
LineNumberTable lineNumberTable = code.getLineNumberTable();
if( lineNumberTable != null ) {
int codePos = getCodePosition();
for( int i = 0; i < lineNumberTable.size(); i++ ) {
int offset = lineNumberTable.getStartOffset( i );
if( offset > codePos ) {
break;
}
lineNumber = lineNumberTable.getLineNumber( i );
}
}
} catch( IOException e ) {
// ignore, line naumber are only needed for debug information
}
return lineNumber;
}

Expand Down
45 changes: 18 additions & 27 deletions src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package de.inetsoftware.jwebassembly.module;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Consumer;

Expand Down Expand Up @@ -149,10 +148,9 @@ private void prepareMethod( MethodInfo method ) throws WasmException {
* if some Java code can't converted
*/
private void writeMethod( MethodInfo method ) throws WasmException {
int lineNumber = -1;
CodeInputStream byteCode = null;
try {
Code code = method.getCode();
lineNumber = code.getFirstLineNr();
if( code != null && method.getAnnotation( "org.webassembly.annotation.Import" ) == null ) { // abstract methods and interface methods does not have code
FunctionName name = new FunctionName( method );
writeExport( name, method );
Expand All @@ -162,19 +160,14 @@ private void writeMethod( MethodInfo method ) throws WasmException {
localVariables.reset();
stackManager.reset();
branchManager.reset();
for( CodeInputStream byteCode : code.getByteCodes() ) {
prepareCodeChunk( byteCode, lineNumber = byteCode.getLineNumber(), method.getConstantPool() );
}
byteCode = code.getByteCode();
prepareCodeChunk( byteCode, method.getConstantPool() );
branchManager.calculate();
localVariables.calculate();

CodeInputStream byteCode = null;
boolean endWithReturn = false;
Iterator<CodeInputStream> byteCodes = code.getByteCodes().iterator();
while( byteCodes.hasNext() ) {
byteCode = byteCodes.next();
endWithReturn = writeCodeChunk( byteCode, lineNumber = byteCode.getLineNumber(), method.getConstantPool() );
}
byteCode = code.getByteCode();
endWithReturn = writeCode( byteCode, method.getConstantPool() );
branchManager.handle( byteCode, writer ); // write the last end operators
if( !endWithReturn && returnType != null ) {
// if a method ends with a loop without a break then code after the loop is no reachable
Expand All @@ -193,12 +186,14 @@ private void writeMethod( MethodInfo method ) throws WasmException {
case f64:
writer.writeConstDouble( 0 );
break;
default:
}
writer.writeBlockCode( WasmBlockOperator.RETURN, null );
}
writer.writeMethodFinish( localVariables.getLocalTypes( paramCount ) );
}
} catch( Exception ioex ) {
int lineNumber = byteCode == null ? -1 : byteCode.getLineNumber();
throw WasmException.create( ioex, sourceFile, lineNumber );
}
}
Expand Down Expand Up @@ -298,14 +293,12 @@ private ValueType getValueType( String signature, int idx ) {
*
* @param byteCode
* a stream of byte code
* @param lineNumber
* the current line number
* @param constantPool
* the constant pool of the the current class
* @throws WasmException
* if some Java code can't converted
*/
private void prepareCodeChunk( CodeInputStream byteCode, int lineNumber, ConstantPool constantPool ) throws WasmException {
private void prepareCodeChunk( CodeInputStream byteCode, ConstantPool constantPool ) throws WasmException {
try {
while( byteCode.available() > 0 ) {
int codePosition = byteCode.getCodePosition();
Expand Down Expand Up @@ -466,15 +459,15 @@ private void prepareCodeChunk( CodeInputStream byteCode, int lineNumber, Constan
case 165: // if_acmpeq
case 166: // if_acmpne
int offset = byteCode.readShort();
branchManager.start( JavaBlockOperator.IF, codePosition, offset, lineNumber );
branchManager.start( JavaBlockOperator.IF, codePosition, offset, byteCode.getLineNumber() );
break;
case 167: // goto
offset = byteCode.readShort();
branchManager.start( JavaBlockOperator.GOTO, codePosition, offset, lineNumber );
branchManager.start( JavaBlockOperator.GOTO, codePosition, offset, byteCode.getLineNumber() );
break;
case 170: // tableswitch
case 171: // lookupswitch
prepareSwitchCode( byteCode, op == 171, lineNumber );
prepareSwitchCode( byteCode, op == 171, byteCode.getLineNumber() );
break;
case 184: // invokestatic
ConstantRef method = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
Expand All @@ -487,7 +480,7 @@ private void prepareCodeChunk( CodeInputStream byteCode, int lineNumber, Constan
}
}
} catch( Exception ex ) {
throw WasmException.create( ex, sourceFile, lineNumber );
throw WasmException.create( ex, sourceFile, byteCode.getLineNumber() );
}
}

Expand Down Expand Up @@ -537,19 +530,17 @@ private void prepareSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch
}

/**
* Write a chunk of byte code.
* Write the byte code of a method.
*
* @param byteCode
* a stream of byte code
* @param lineNumber
* the current line number
* @param constantPool
* the constant pool of the the current class
* @throws WasmException
* if some Java code can't converted
* @return true, if the last operation was a return
*/
private boolean writeCodeChunk( CodeInputStream byteCode, int lineNumber, ConstantPool constantPool ) throws WasmException {
private boolean writeCode( CodeInputStream byteCode, ConstantPool constantPool ) throws WasmException {
boolean endWithReturn = false;
try {
while( byteCode.available() > 0 ) {
Expand Down Expand Up @@ -681,7 +672,7 @@ private boolean writeCodeChunk( CodeInputStream byteCode, int lineNumber, Consta
case 94: // dup2_x2
case 95: // swap
// can be do with functions with more as one return value in future WASM standard
throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + op, sourceFile, lineNumber );
throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + op, sourceFile, byteCode.getLineNumber() );
case 96: // iadd
writer.writeNumericOperator( NumericOperator.add, ValueType.i32);
break;
Expand Down Expand Up @@ -739,7 +730,7 @@ private boolean writeCodeChunk( CodeInputStream byteCode, int lineNumber, Consta
case 114: // frem
case 115: // drem
//TODO can be implemented with a helper function like: (a - (long)(a / b) * (double)b)
throw new WasmException( "Modulo/Remainder for floating numbers is not supported in WASM. Use int or long data types." + op, sourceFile, lineNumber );
throw new WasmException( "Modulo/Remainder for floating numbers is not supported in WASM. Use int or long data types." + op, sourceFile, byteCode.getLineNumber() );
case 116: // ineg
writer.writeConstInt( -1 );
writer.writeNumericOperator( NumericOperator.mul, ValueType.i32 );
Expand Down Expand Up @@ -922,13 +913,13 @@ private boolean writeCodeChunk( CodeInputStream byteCode, int lineNumber, Consta
writer.writeFunctionCall( method.getConstantClass().getName() + '.' + method.getName() + method.getType() );
break;
default:
throw new WasmException( "Unimplemented Java byte code operation: " + op, sourceFile, lineNumber );
throw new WasmException( "Unimplemented Java byte code operation: " + op, sourceFile, byteCode.getLineNumber() );
}
}
} catch( WasmException ex ) {
throw ex;
} catch( Exception ex ) {
throw WasmException.create( ex, sourceFile, lineNumber );
throw WasmException.create( ex, sourceFile, byteCode.getLineNumber() );
}
return endWithReturn;
}
Expand Down

0 comments on commit ecd61dc

Please sign in to comment.