mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
Implements more if(compare) operation codes
This commit is contained in:
parent
b29adc7437
commit
2cb0988e68
@ -16,8 +16,8 @@ Status of the project
|
||||
* Public API of the Compiler
|
||||
|
||||
### Partially Finished
|
||||
* Binary format file writer (134 of 201 byte code instructions)
|
||||
* Text format file writer (134 of 201 byte code instructions)
|
||||
* Binary format file writer (145 of 201 byte code instructions)
|
||||
* Text format file writer (145 of 201 byte code instructions)
|
||||
|
||||
### Open Features
|
||||
* Exception handling - required the next version of WebAssembly
|
||||
|
@ -530,7 +530,7 @@ public abstract class ModuleWriter implements Closeable {
|
||||
int op = byteCode.readUnsignedByte();
|
||||
switch( op ) {
|
||||
case 0: // nop
|
||||
return;
|
||||
break;
|
||||
//TODO case 1: // aconst_null
|
||||
case 2: // iconst_m1
|
||||
case 3: // iconst_0
|
||||
@ -824,6 +824,17 @@ public abstract class ModuleWriter implements Closeable {
|
||||
writeConstInt( 16 );
|
||||
writeNumericOperator( NumericOperator.shr_s, ValueType.i32 );
|
||||
break;
|
||||
case 148: // lcmp
|
||||
opCompare( ValueType.i64, byteCode );
|
||||
break;
|
||||
case 149: // fcmpl
|
||||
case 150: // fcmpg
|
||||
opCompare( ValueType.f32, byteCode );
|
||||
break;
|
||||
case 151: // dcmpl
|
||||
case 152: // dcmpg
|
||||
opCompare( ValueType.f64, byteCode );
|
||||
break;
|
||||
case 153: // ifeq
|
||||
opIfCondition( NumericOperator.ne, byteCode );
|
||||
break;
|
||||
@ -842,8 +853,28 @@ public abstract class ModuleWriter implements Closeable {
|
||||
case 158: // ifle
|
||||
opIfCondition( NumericOperator.ge_s, byteCode );
|
||||
break;
|
||||
case 159: // if_icmpeq
|
||||
opIfCompareCondition( NumericOperator.ne, byteCode );
|
||||
break;
|
||||
case 160: // if_icmpne
|
||||
opIfCompareCondition( NumericOperator.eq, byteCode );
|
||||
break;
|
||||
case 161: // if_icmplt
|
||||
opIfCompareCondition( NumericOperator.gt, byteCode );
|
||||
break;
|
||||
case 162: // if_icmpge
|
||||
opIfCompareCondition( NumericOperator.le_s, byteCode );
|
||||
break;
|
||||
case 163: // if_icmpgt
|
||||
opIfCompareCondition( NumericOperator.lt_s, byteCode );
|
||||
break;
|
||||
case 164: // if_icmple
|
||||
opIfCompareCondition( NumericOperator.ge_s, byteCode );
|
||||
break;
|
||||
//TODO case 165: // if_acmpeq
|
||||
//TODO case 166: // if_acmpne
|
||||
case 167: // goto
|
||||
byteCode.skip(2);
|
||||
byteCode.skip(2); // handle in the branch manager
|
||||
break;
|
||||
case 170: // tableswitch
|
||||
case 171: // lookupswitch
|
||||
@ -984,6 +1015,63 @@ public abstract class ModuleWriter implements Closeable {
|
||||
writeNumericOperator( numOp, ValueType.i32 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the if<condition> of the Java byte code. This Java instruction compare the first stack value with value 0.
|
||||
* Important: In Java the condition for the jump to the else block is saved. In WebAssembler we need to use
|
||||
* condition for the if block. The caller of the method must already negate this
|
||||
*
|
||||
* @param numOp
|
||||
* The condition for the if block.
|
||||
* @param byteCode
|
||||
* current byte code stream to read the target offset.
|
||||
* @throws IOException
|
||||
* if any I/O errors occur.
|
||||
*/
|
||||
private void opIfCompareCondition( NumericOperator numOp, CodeInputStream byteCode ) throws IOException {
|
||||
byteCode.skip(2);
|
||||
writeNumericOperator( numOp, ValueType.i32 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the different compare operator. The compare operator returns the integer values -1, 0 or 1. There is no
|
||||
* equivalent in WebAssembly. That we need to read the next operation to find an equivalent.
|
||||
*
|
||||
* @param valueType
|
||||
* the value type of the compared
|
||||
* @param byteCode
|
||||
* current byte code stream to read the next operation.
|
||||
* @throws IOException
|
||||
* if any I/O errors occur.
|
||||
*/
|
||||
private void opCompare( ValueType valueType, CodeInputStream byteCode ) throws IOException {
|
||||
NumericOperator numOp;
|
||||
int nextOp = byteCode.read();
|
||||
switch( nextOp ){
|
||||
case 153: // ifeq
|
||||
numOp = NumericOperator.ne;
|
||||
break;
|
||||
case 154: // ifne
|
||||
numOp = NumericOperator.eq;
|
||||
break;
|
||||
case 155: // iflt
|
||||
numOp = NumericOperator.gt;
|
||||
break;
|
||||
case 156: // ifge
|
||||
numOp = NumericOperator.le_s;
|
||||
break;
|
||||
case 157: // ifgt
|
||||
numOp = NumericOperator.lt_s;
|
||||
break;
|
||||
case 158: // ifle
|
||||
numOp = NumericOperator.ge_s;
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 );
|
||||
}
|
||||
byteCode.skip(2);
|
||||
writeNumericOperator( numOp, valueType );
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a constant value.
|
||||
*
|
||||
|
@ -43,6 +43,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
addParam( list, script, "ifne" );
|
||||
addParam( list, script, "iflt" );
|
||||
addParam( list, script, "ifMultiple" );
|
||||
addParam( list, script, "ifCompare" );
|
||||
addParam( list, script, "switchDirect" );
|
||||
addParam( list, script, "forLoop" );
|
||||
}
|
||||
@ -96,9 +97,46 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
condition--;
|
||||
}
|
||||
}
|
||||
if( condition > 2 ) {
|
||||
condition++;
|
||||
} else {
|
||||
condition = 0;
|
||||
}
|
||||
if( condition >= 2 ) {
|
||||
condition++;
|
||||
} else {
|
||||
condition = 0;
|
||||
}
|
||||
if( condition <= 123 ) {
|
||||
condition++;
|
||||
} else {
|
||||
condition = 0;
|
||||
}
|
||||
if( condition < 123 ) {
|
||||
condition++;
|
||||
} else {
|
||||
condition = 0;
|
||||
}
|
||||
if( condition != 123 ) {
|
||||
condition++;
|
||||
} else {
|
||||
condition = 0;
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifCompare() {
|
||||
double condition = 3.0;
|
||||
int result;
|
||||
if( condition >= 3.5 ) {
|
||||
result = 13;
|
||||
} else {
|
||||
result = 76;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Export
|
||||
static int switchDirect() {
|
||||
return tableSwitch(10) + (tableSwitch( 9 ) * 10) + (lookupSwitch(Integer.MAX_VALUE) * 100) + (lookupSwitch(0) * 1000);
|
||||
@ -123,8 +161,14 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
b = 1;
|
||||
break;
|
||||
case 1000:
|
||||
b = 2;
|
||||
break;
|
||||
case 1001:
|
||||
if( a == 1000 ) {
|
||||
b = 2;
|
||||
break;
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
//$FALL-THROUGH$
|
||||
case Integer.MAX_VALUE:
|
||||
b = 3;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user