implements dup_x2 instruction

This commit is contained in:
Volker Berlin 2020-04-25 22:22:18 +02:00
parent f15fb1cdf9
commit 11f338eea8
3 changed files with 49 additions and 3 deletions

View File

@ -311,9 +311,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
break;
case 91: // dup_x2
case 94: // dup2_x2
addDupX2Instruction( codePos, lineNumber );
break;
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: "
throw new WasmException( "Stack swap is not supported in current WASM. try to save immediate values in a local variable: "
+ op, lineNumber );
case 96: // iadd
addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber );

View File

@ -348,7 +348,7 @@ public abstract class WasmCodeBuilder {
AnyType type2 = findValueTypeFromStack( 2, javaCodePos );
int varIndex1 = getTempVariable( type1, javaCodePos, javaCodePos + 1 );
int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 );;
int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 );
// save in temp variables
instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex1, localVariables, javaCodePos, lineNumber ) );
@ -360,6 +360,37 @@ public abstract class WasmCodeBuilder {
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) );
}
/**
* Simulate the dup_x2 Java byte code instruction.<p>
*
* ..., value3, value2, value1 ..., value1, value3, value2, value1
*
* @param javaCodePos
* the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/
protected void addDupX2Instruction( int javaCodePos, int lineNumber ) {
AnyType type1 = findValueTypeFromStack( 1, javaCodePos );
AnyType type2 = findValueTypeFromStack( 2, javaCodePos );
AnyType type3 = findValueTypeFromStack( 3, javaCodePos );
int varIndex1 = getTempVariable( type1, javaCodePos, javaCodePos + 1 );
int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 );
int varIndex3 = getTempVariable( type3, javaCodePos, javaCodePos + 1 );
// save in temp variables
instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex1, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex2, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex3, localVariables, javaCodePos, lineNumber ) );
// and restore it in new order on the stack
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex3, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex2, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) );
}
/**
* Add a global instruction
*

View File

@ -59,6 +59,7 @@ public class ArrayOperations extends AbstractBaseTest {
addParam( list, script, "loopObject" );
addParam( list, script, "copyBack2Front" );
addParam( list, script, "copyFront2Back" );
addParam( list, script, "dup_x2" );
}
rule.setTestParameters( list );
return list;
@ -183,5 +184,18 @@ public class ArrayOperations extends AbstractBaseTest {
crc.update( a );
return crc.getValue();
}
@Export
static int dup_x2() {
Object[] data = {null,null,null};
int index = 1;
Object value = null;
if ((data[index] = value) != null) { // test for instruction dup_x2
return 1;
} else {
return 2;
}
}
}
}