negate compare condition of if operations in the branch manager instead on parsing the byte code.

This commit is contained in:
Volker 2018-08-03 18:04:08 +02:00
parent fbe2d97fc6
commit e3764913c3
2 changed files with 34 additions and 36 deletions

View File

@ -188,6 +188,7 @@ class BranchManger {
allParsedOperations.remove( n ); allParsedOperations.remove( n );
instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) ); instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) );
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) ); instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) );
((IfParsedBlock)nextBlock).negateCompare();
break; break;
} }
} }
@ -211,7 +212,7 @@ class BranchManger {
ParsedBlock parsedBlock = parsedOperations.remove( 0 ); ParsedBlock parsedBlock = parsedOperations.remove( 0 );
switch( parsedBlock.op ) { switch( parsedBlock.op ) {
case IF: case IF:
calculateIf( parent, parsedBlock, parsedOperations ); calculateIf( parent, (IfParsedBlock)parsedBlock, parsedOperations );
break; break;
case SWITCH: case SWITCH:
calculateSwitch( parent, (SwitchParsedBlock)parsedBlock, parsedOperations ); calculateSwitch( parent, (SwitchParsedBlock)parsedBlock, parsedOperations );
@ -238,7 +239,7 @@ class BranchManger {
* @param parsedOperations * @param parsedOperations
* the not consumed operations in the parent branch * the not consumed operations in the parent branch
*/ */
private void calculateIf( BranchNode parent, ParsedBlock startBlock, List<ParsedBlock> parsedOperations ) { private void calculateIf( BranchNode parent, IfParsedBlock startBlock, List<ParsedBlock> parsedOperations ) {
int i = 0; int i = 0;
int endPos = Math.min( startBlock.endPosition, parent.endPos ); int endPos = Math.min( startBlock.endPosition, parent.endPos );
int startPos = startBlock.startPosition + 3; int startPos = startBlock.startPosition + 3;
@ -280,6 +281,7 @@ class BranchManger {
branch = new BranchNode( startPos, endPos, WasmBlockOperator.IF, WasmBlockOperator.END ); branch = new BranchNode( startPos, endPos, WasmBlockOperator.IF, WasmBlockOperator.END );
parent.add( branch ); parent.add( branch );
} }
startBlock.negateCompare();
/** /**
* Search the index in the stack to add the END operator * Search the index in the stack to add the END operator
@ -596,7 +598,7 @@ class BranchManger {
/** /**
* Negate the compare operation. * Negate the compare operation.
*/ */
private void negate() { private void negateCompare() {
NumericOperator newOp; NumericOperator newOp;
switch( instr.numOp ) { switch( instr.numOp ) {
case eq: case eq:

View File

@ -538,7 +538,7 @@ public class ModuleGenerator {
case 132: // iinc case 132: // iinc
int idx = byteCode.readUnsignedByte(); int idx = byteCode.readUnsignedByte();
instructions.add( new WasmLoadStoreInstruction( true, idx, localVariables, codePos ) ); instructions.add( new WasmLoadStoreInstruction( true, idx, localVariables, codePos ) );
instructions.add( new WasmConstInstruction( byteCode.readUnsignedByte(), codePos ) ); instructions.add( new WasmConstInstruction( (int)byteCode.readByte(), codePos ) );
instructions.add( new WasmNumericInstruction( NumericOperator.add, ValueType.i32, codePos) ); instructions.add( new WasmNumericInstruction( NumericOperator.add, ValueType.i32, codePos) );
instr = new WasmLoadStoreInstruction( false, idx, localVariables, codePos ); instr = new WasmLoadStoreInstruction( false, idx, localVariables, codePos );
break; break;
@ -606,40 +606,40 @@ public class ModuleGenerator {
opCompare( ValueType.f64, byteCode, codePos ); opCompare( ValueType.f64, byteCode, codePos );
break; break;
case 153: // ifeq case 153: // ifeq
opIfCondition( NumericOperator.ne, NumericOperator.eq, byteCode, codePos ); opIfCondition( NumericOperator.eq, byteCode, codePos );
break; break;
case 154: // ifne case 154: // ifne
opIfCondition( NumericOperator.eq, NumericOperator.ne, byteCode, codePos ); opIfCondition( NumericOperator.ne, byteCode, codePos );
break; break;
case 155: // iflt case 155: // iflt
opIfCondition( NumericOperator.ge_s, NumericOperator.lt_s, byteCode, codePos ); opIfCondition( NumericOperator.lt_s, byteCode, codePos );
break; break;
case 156: // ifge case 156: // ifge
opIfCondition( NumericOperator.lt_s, NumericOperator.ge_s, byteCode, codePos ); opIfCondition( NumericOperator.ge_s, byteCode, codePos );
break; break;
case 157: // ifgt case 157: // ifgt
opIfCondition( NumericOperator.le_s, NumericOperator.gt, byteCode, codePos ); opIfCondition( NumericOperator.gt, byteCode, codePos );
break; break;
case 158: // ifle case 158: // ifle
opIfCondition( NumericOperator.gt, NumericOperator.le_s, byteCode, codePos ); opIfCondition( NumericOperator.le_s, byteCode, codePos );
break; break;
case 159: // if_icmpeq case 159: // if_icmpeq
opIfCompareCondition( NumericOperator.ne, NumericOperator.eq, byteCode, codePos ); opIfCompareCondition( NumericOperator.eq, byteCode, codePos );
break; break;
case 160: // if_icmpne case 160: // if_icmpne
opIfCompareCondition( NumericOperator.eq, NumericOperator.ne, byteCode, codePos ); opIfCompareCondition( NumericOperator.ne, byteCode, codePos );
break; break;
case 161: // if_icmplt case 161: // if_icmplt
opIfCompareCondition( NumericOperator.ge_s, NumericOperator.lt_s, byteCode, codePos ); opIfCompareCondition( NumericOperator.lt_s, byteCode, codePos );
break; break;
case 162: // if_icmpge case 162: // if_icmpge
opIfCompareCondition( NumericOperator.lt_s, NumericOperator.ge_s, byteCode, codePos ); opIfCompareCondition( NumericOperator.ge_s, byteCode, codePos );
break; break;
case 163: // if_icmpgt case 163: // if_icmpgt
opIfCompareCondition( NumericOperator.le_s, NumericOperator.gt, byteCode, codePos ); opIfCompareCondition( NumericOperator.gt, byteCode, codePos );
break; break;
case 164: // if_icmple case 164: // if_icmple
opIfCompareCondition( NumericOperator.gt, NumericOperator.le_s, byteCode, codePos ); opIfCompareCondition( NumericOperator.le_s, byteCode, codePos );
break; break;
//TODO case 165: // if_acmpeq //TODO case 165: // if_acmpeq
//TODO case 166: // if_acmpne //TODO case 166: // if_acmpne
@ -819,42 +819,38 @@ public class ModuleGenerator {
* Handle the if<condition> of the Java byte code. This Java instruction compare the first stack value with value 0. * Handle the if<condition> of the Java byte code. This Java instruction compare the first stack value with value 0.
* Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we * Important: In the Java IF expression 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 * need to use condition for the if block. The caller of the method must already negate this
* * @param compareOp
* @param ifNumOp
* The condition for the if block.
* @param continueNumOp
* The condition for the continue of a loop. * The condition for the continue of a loop.
* @param byteCode * @param byteCode
* current byte code stream to read the target offset. * current byte code stream to read the target offset.
* @param codePos * @param codePos
* the code position/offset in the Java method * the code position/offset in the Java method
*
* @throws IOException * @throws IOException
* if any I/O errors occur. * if any I/O errors occur.
*/ */
private void opIfCondition( NumericOperator ifNumOp, NumericOperator continueNumOp, CodeInputStream byteCode, int codePos ) throws IOException { private void opIfCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos ) throws IOException {
instructions.add( new WasmConstInstruction( 0, codePos ) ); instructions.add( new WasmConstInstruction( 0, codePos ) );
opIfCompareCondition( ifNumOp, continueNumOp, byteCode, codePos ); opIfCompareCondition( compareOp, byteCode, codePos );
} }
/** /**
* Handle the if<condition> of the Java byte code. This Java instruction compare 2 values from stack. * Handle the if<condition> of the Java byte code. This Java instruction compare 2 values from stack.
* Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we need to use * Important: In the Java IF expression 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. * condition for the if block. The caller of the method must already negate this.
* * @param compareOp
* @param ifNumOp
* The condition for the if block.
* @param continueNumOp
* The condition for the continue of a loop. * The condition for the continue of a loop.
* @param byteCode * @param byteCode
* current byte code stream to read the target offset. * current byte code stream to read the target offset.
* @param codePos * @param codePos
* the code position/offset in the Java method * the code position/offset in the Java method
*
* @throws IOException * @throws IOException
* if any I/O errors occur. * if any I/O errors occur.
*/ */
private void opIfCompareCondition( NumericOperator ifNumOp, NumericOperator continueNumOp, CodeInputStream byteCode, int codePos ) throws IOException { private void opIfCompareCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos ) throws IOException {
int offset = byteCode.readShort(); int offset = byteCode.readShort();
WasmNumericInstruction compare = new WasmNumericInstruction( offset > 0 ? ifNumOp : continueNumOp, ValueType.i32, codePos ); WasmNumericInstruction compare = new WasmNumericInstruction( compareOp, ValueType.i32, codePos );
branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare ); branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare );
instructions.add( compare ); instructions.add( compare );
} }
@ -878,22 +874,22 @@ public class ModuleGenerator {
int nextOp = byteCode.read(); int nextOp = byteCode.read();
switch( nextOp ){ switch( nextOp ){
case 153: // ifeq case 153: // ifeq
numOp = NumericOperator.ne;
break;
case 154: // ifne
numOp = NumericOperator.eq; numOp = NumericOperator.eq;
break; break;
case 155: // iflt case 154: // ifne
numOp = NumericOperator.ge_s; numOp = NumericOperator.ne;
break; break;
case 156: // ifge case 155: // iflt
numOp = NumericOperator.lt_s; numOp = NumericOperator.lt_s;
break; break;
case 156: // ifge
numOp = NumericOperator.ge_s;
break;
case 157: // ifgt case 157: // ifgt
numOp = NumericOperator.le_s; numOp = NumericOperator.gt;
break; break;
case 158: // ifle case 158: // ifle
numOp = NumericOperator.gt; numOp = NumericOperator.le_s;
break; break;
default: default:
throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 ); throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 );