add support for locals in WatParser

This commit is contained in:
Volker Berlin 2019-11-12 20:47:57 +01:00
parent c6d569c66c
commit 63a7c487c0
2 changed files with 51 additions and 32 deletions

View File

@ -84,14 +84,16 @@ class LocaleVariableManager {
void reset( LocalVariableTable variableTable, MethodInfo method ) {
size = 0;
int maxLocals;
if( variableTable == null ) {
return;
}
maxLocals = 0;
} else {
maxLocals = variableTable.getMaxLocals();
/**
* Java can use reuse a variable slot in a different block. The type can be different in the block. WebAssembly
* does not support a type change for a local variable. That we need to create 2 variables. This try the follow
* complex code.
* Java can reuse a variable slot in a different block. The type can be different in the block. WebAssembly
* does not support a type change for a local variable. That we need to create 2 variables. This try the
* follow complex code.
*/
LocalVariable[] vars = variableTable.getTable();
@ -116,7 +118,9 @@ class LocaleVariableManager {
return comp;
}
return Integer.compare( v1.startPos, v2.startPos );
} );
}
// reduce all duplications if there are no conflicts and expands startPos and endPos
for( int i = 0; i < size - 1; i++ ) {
@ -152,15 +156,13 @@ class LocaleVariableManager {
var.name = findUniqueVarName( var.name );
}
int maxLocals = variableTable.getMaxLocals();
// add missing slots from signature
if( maxLocals > 0 && vars.length == 0 && method != null ) {
if( (maxLocals > 0 || variableTable == null) && size == 0 && method != null ) {
ValueTypeParser parser = new ValueTypeParser( method.getType(), types );
if( !method.isStatic() ) {
resetAddVar( ValueType.anyref, size );
}
while( size < maxLocals ) {
while( true ) {
AnyType type = parser.next();
if( type == null ) {
break;
@ -235,6 +237,10 @@ class LocaleVariableManager {
*/
void use( AnyType valueType, int slot, int javaCodePos ) {
int idx = get( slot, javaCodePos );
useImpl( valueType, idx );
}
private void useImpl( AnyType valueType, int idx ) {
Variable var = variables[idx];
if( var.valueType != null && var.valueType != valueType ) {
if( var.valueType.getCode() >= 0 && valueType == ValueType.anyref ) {
@ -252,6 +258,13 @@ return;// TODO we need a better check
var.valueType = valueType;
}
void useIndex( AnyType valueType, int wasmIdx ) {
while( size <= wasmIdx ) {
resetAddVar( null, size );
}
useImpl( valueType, wasmIdx );
}
/**
* Calculate the WebAssembly index position on the consumed data.
*/

View File

@ -266,6 +266,12 @@ public abstract class WasmCodeBuilder {
*/
@Nonnull
protected void addLocalInstruction( VariableOperator op, @Nonnegative int wasmIdx, int javaCodePos, int lineNumber ) {
switch( op ) {
case set:
case tee:
AnyType valueType = findValueTypeFromStack( 1 );
localVariables.useIndex( valueType, wasmIdx );
}
instructions.add( new WasmLocalInstruction( op, wasmIdx, javaCodePos, lineNumber ) );
}