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(); int codePos = byteCode.getCodePosition();
endWithReturn = false; endWithReturn = false;
int op = byteCode.readUnsignedByte(); int op = byteCode.readUnsignedByte();
switch( op ) { OP: switch( op ) {
case 0: // nop case 0: // nop
break; break;
//TODO case 1: // aconst_null //TODO case 1: // aconst_null
@ -224,11 +224,24 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
addBlockInstruction( WasmBlockOperator.DROP, null, codePos ); addBlockInstruction( WasmBlockOperator.DROP, null, codePos );
break; break;
case 89: // dup: duplicate the value on top of the stack case 89: // dup: duplicate the value on top of the stack
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_i32", "(I)II" ), codePos ); case 92: // dup2
break; 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 90: // dup_x1
case 91: // dup_x2 case 91: // dup_x2
case 92: // dup2
case 93: // dup2_x1 case 93: // dup2_x1
case 94: // dup2_x2 case 94: // dup2_x2
case 95: // swap case 95: // swap
@ -557,7 +570,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
byteCode.skip( 4 - padding ); byteCode.skip( 4 - padding );
} }
startPosition--; startPosition--;
int switchValuestartPosition = findPreviousPushCodePosition(); int switchValuestartPosition = findPreviousPushInstruction().getCodePosition();
int defaultPosition = startPosition + byteCode.readInt(); int defaultPosition = startPosition + byteCode.readInt();
int[] keys; 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. * 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; int valueCount = 0;
List<WasmInstruction> instructions = getInstructions(); List<WasmInstruction> instructions = getInstructions();
for( int i = instructions.size() - 1; i >= 0; i-- ) { for( int i = instructions.size() - 1; i >= 0; i-- ) {
@ -636,10 +650,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
} }
valueCount -= instr.getPopCount(); valueCount -= instr.getPopCount();
if( valueCount == 1 ) { 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" ) @WasmTextCode( signature = "(I)II", value = "get_local 0 get_local 0 return" )
native static void dup_i32(); 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 if( script == ScriptEngine.SpiderMonkey ) { //TODO SpiderMonkey does not support multiple return values
continue; continue;
} }
addParam( list, script, "simple" ); addParam( list, script, "dupInt" );
addParam( list, script, "dupFloat" );
addParam( list, script, "dupDouble" );
addParam( list, script, "dupLong" );
} }
return list; return list;
} }
@ -53,11 +56,35 @@ public class Stacks extends AbstractBaseTest {
static class TestClass { static class TestClass {
@Export @Export
static int simple() { static int dupInt() {
int a = 1; int a = 1;
int b = 2; int b = 2;
a = b = 3; a = b = 3;
return b; 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;
}
} }
} }