more dup operations

This commit is contained in:
Volker Berlin 2018-11-26 20:35:50 +01:00
parent a8a9d9eb1e
commit b2a359746d
3 changed files with 62 additions and 13 deletions

View File

@ -80,7 +80,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
int codePos = byteCode.getCodePosition();
endWithReturn = false;
int op = byteCode.readUnsignedByte();
switch( op ) {
OP: switch( op ) {
case 0: // nop
break;
//TODO case 1: // aconst_null
@ -224,11 +224,24 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
addBlockInstruction( WasmBlockOperator.DROP, null, codePos );
break;
case 89: // dup: duplicate the value on top of the stack
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_i32", "(I)II" ), codePos );
break;
case 92: // dup2
switch( findPreviousPushInstruction().getPushValueType() ) {
case i32:
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_i32", "(I)II" ), codePos );
break OP;
case f32:
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_f32", "(F)FF" ), codePos );
break OP;
case i64:
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_i64", "(J)JJ" ), codePos );
break OP;
case f64:
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_f64", "(D)DD" ), codePos );
break OP;
}
//$FALL-THROUGH$
case 90: // dup_x1
case 91: // dup_x2
case 92: // dup2
case 93: // dup2_x1
case 94: // dup2_x2
case 95: // swap
@ -557,7 +570,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
byteCode.skip( 4 - padding );
}
startPosition--;
int switchValuestartPosition = findPreviousPushCodePosition();
int switchValuestartPosition = findPreviousPushInstruction().getCodePosition();
int defaultPosition = startPosition + byteCode.readInt();
int[] keys;
@ -620,12 +633,13 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
}
/**
* We need one value from the stack inside of a block. We need to find the code position on which the block can
* We need one value from the stack inside of a block. We need to find the WasmInstruction on which the block can
* start. If this a function call or numeric expression this can be complex to find the right point.
*
* @return the code position
* @return the WasmInstruction that push the last instruction
*/
private int findPreviousPushCodePosition() {
@Nonnull
private WasmInstruction findPreviousPushInstruction() {
int valueCount = 0;
List<WasmInstruction> instructions = getInstructions();
for( int i = instructions.size() - 1; i >= 0; i-- ) {
@ -636,10 +650,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
}
valueCount -= instr.getPopCount();
if( valueCount == 1 ) {
return instr.getCodePosition();
return instr;
}
}
throw new WasmException( "Switch start position not found", -1 ); // should never occur
throw new WasmException( "Start position not found", -1 ); // should never occur
}
/**

View File

@ -22,4 +22,12 @@ public class NativeHelperCode {
@WasmTextCode( signature = "(I)II", value = "get_local 0 get_local 0 return" )
native static void dup_i32();
}
@WasmTextCode( signature = "(F)FF", value = "get_local 0 get_local 0 return" )
native static void dup_f32();
@WasmTextCode( signature = "(J)JJ", value = "get_local 0 get_local 0 return" )
native static void dup_i64();
@WasmTextCode( signature = "(D)DD", value = "get_local 0 get_local 0 return" )
native static void dup_f64();
}

View File

@ -45,7 +45,10 @@ public class Stacks extends AbstractBaseTest {
if( script == ScriptEngine.SpiderMonkey ) { //TODO SpiderMonkey does not support multiple return values
continue;
}
addParam( list, script, "simple" );
addParam( list, script, "dupInt" );
addParam( list, script, "dupFloat" );
addParam( list, script, "dupDouble" );
addParam( list, script, "dupLong" );
}
return list;
}
@ -53,11 +56,35 @@ public class Stacks extends AbstractBaseTest {
static class TestClass {
@Export
static int simple() {
static int dupInt() {
int a = 1;
int b = 2;
a = b = 3;
return b;
}
@Export
static float dupFloat() {
float a = 1;
float b = 2;
a = b = 3.25F;
return b;
}
@Export
static double dupDouble() {
double a = 1;
double b = 2;
a = b = 3.25;
return b;
}
@Export
static int dupLong() {
long a = 1;
long b = 2;
a = b = 3;
return (int)b;
}
}
}