Add return values of method calls to the stack manager

This commit is contained in:
Volker Berlin 2018-05-30 19:59:45 +02:00
parent 7d53f8d549
commit 6ffd004c2b

View File

@ -155,6 +155,7 @@ public abstract class ModuleWriter implements Closeable {
int lineNumber = -1; int lineNumber = -1;
try { try {
Code code = method.getCode(); 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 if( code != null && method.getAnnotation( "org.webassembly.annotation.Import" ) == null ) { // abstract methods and interface methods does not have code
FunctionName name = new FunctionName( method ); FunctionName name = new FunctionName( method );
writeExport( name, method ); writeExport( name, method );
@ -165,7 +166,7 @@ public abstract class ModuleWriter implements Closeable {
stackManager.reset(); stackManager.reset();
branchManager.reset(); branchManager.reset();
for( CodeInputStream byteCode : code.getByteCodes() ) { for( CodeInputStream byteCode : code.getByteCodes() ) {
prepareCodeChunk( byteCode, lineNumber = byteCode.getLineNumber() ); prepareCodeChunk( byteCode, lineNumber = byteCode.getLineNumber(), method.getConstantPool() );
} }
branchManager.calculate(); branchManager.calculate();
localVariables.calculate(); localVariables.calculate();
@ -266,49 +267,56 @@ public abstract class ModuleWriter implements Closeable {
ValueType type = null; ValueType type = null;
for( int i = 1; i < signature.length(); i++ ) { for( int i = 1; i < signature.length(); i++ ) {
paramCount++; paramCount++;
String javaType = null; if( signature.charAt( i ) == ')' ) {
type = null; this.paramCount = paramCount - 1;
switch( signature.charAt( i ) ) { kind = "result";
case '[': // array continue;
javaType = "array";
break;
case 'L':
javaType = "object";
break;
case 'B': // byte
case 'C': // char
case 'S': // short
case 'I': // int
type = ValueType.i32;
break;
case 'D': // double
type = ValueType.f64;
break;
case 'F': // float
type = ValueType.f32;
break;
case 'J': // long
type = ValueType.i64;
break;
case 'V': // void
continue;
case ')':
this.paramCount = paramCount - 1;
kind = "result";
continue;
default:
javaType = signature.substring( i, i + 1 );
} }
type = getValueType( signature, i );
if( type != null ) { if( type != null ) {
writeMethodParam( kind, type ); writeMethodParam( kind, type );
} else {
int lineNumber = method.getCode().getFirstLineNr();
throw new WasmException( "Not supported Java data type in method signature: " + javaType, sourceFile, lineNumber );
} }
} }
this.returnType = type; this.returnType = type;
} }
/**
* Get the WebAssembly value type from a Java signature.
*
* @param signature
* the signature
* @param idx
* the index in the signature
* @return the value type or null if void
*/
private ValueType getValueType( String signature, int idx ) {
String javaType;
switch( signature.charAt( idx ) ) {
case '[': // array
javaType = "array";
break;
case 'L':
javaType = "object";
break;
case 'B': // byte
case 'C': // char
case 'S': // short
case 'I': // int
return ValueType.i32;
case 'D': // double
return ValueType.f64;
case 'F': // float
return ValueType.f32;
case 'J': // long
return ValueType.i64;
case 'V': // void
return null;
default:
javaType = signature.substring( idx, idx + 1 );
}
throw new WasmException( "Not supported Java data type in method signature: " + javaType, sourceFile, -1 );
}
/** /**
* Write a method parameter. * Write a method parameter.
* *
@ -339,10 +347,12 @@ public abstract class ModuleWriter implements Closeable {
* a stream of byte code * a stream of byte code
* @param lineNumber * @param lineNumber
* the current line number * the current line number
* @param constantPool
* the constant pool of the the current class
* @throws WasmException * @throws WasmException
* if some Java code can't converted * if some Java code can't converted
*/ */
private void prepareCodeChunk( CodeInputStream byteCode, int lineNumber ) throws WasmException { private void prepareCodeChunk( CodeInputStream byteCode, int lineNumber, ConstantPool constantPool ) throws WasmException {
try { try {
while( byteCode.available() > 0 ) { while( byteCode.available() > 0 ) {
int codePosition = byteCode.getCodePosition(); int codePosition = byteCode.getCodePosition();
@ -486,7 +496,6 @@ public abstract class ModuleWriter implements Closeable {
byteCode.skip(1); byteCode.skip(1);
break; break;
case 132: // iinc case 132: // iinc
case 184: // invokestatic
byteCode.skip( 2); byteCode.skip( 2);
break; break;
case 153: // ifeq case 153: // ifeq
@ -514,6 +523,14 @@ public abstract class ModuleWriter implements Closeable {
case 171: // lookupswitch case 171: // lookupswitch
prepareSwitchCode( byteCode, op == 171, lineNumber ); prepareSwitchCode( byteCode, op == 171, lineNumber );
break; break;
case 184: // invokestatic
ConstantRef method = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
String signature = method.getType();
ValueType type = getValueType( signature, signature.indexOf( ')' ) + 1 );
if( type != null ) {
stackManager.add( type, codePosition );
}
break;
} }
} }
} catch( Exception ex ) { } catch( Exception ex ) {