mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
extract method writeSwitchCode()
This commit is contained in:
parent
6c971c6525
commit
6a7744e228
@ -831,66 +831,7 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
break;
|
break;
|
||||||
case 170: // tableswitch
|
case 170: // tableswitch
|
||||||
case 171: // lookupswitch
|
case 171: // lookupswitch
|
||||||
int startPosition = byteCode.getCodePosition();
|
writeSwitchCode( byteCode, op == 171 );
|
||||||
int padding = startPosition % 4;
|
|
||||||
if( padding > 0 ) {
|
|
||||||
byteCode.skip( 4 - padding );
|
|
||||||
}
|
|
||||||
startPosition--;
|
|
||||||
|
|
||||||
int defaultPosition = byteCode.readInt();
|
|
||||||
if( op == 171 ) { // lookupswitch
|
|
||||||
int count = byteCode.readInt();
|
|
||||||
int[] keys = new int[count];
|
|
||||||
int[] positions = new int[count];
|
|
||||||
for( int i = 0; i < count; i++ ) {
|
|
||||||
keys[i] = byteCode.readInt();
|
|
||||||
positions[i] = byteCode.readInt();
|
|
||||||
}
|
|
||||||
int tempI32 = localVariables.getTempI32();
|
|
||||||
int block = 0;
|
|
||||||
int defaultBlock = -1;
|
|
||||||
int currentPos = -1;
|
|
||||||
writeLoadStore( false, tempI32 );
|
|
||||||
do {
|
|
||||||
int nextPos = findNext( currentPos, positions );
|
|
||||||
if( nextPos == currentPos ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentPos = nextPos;
|
|
||||||
if( defaultBlock < 0 ) {
|
|
||||||
if( defaultPosition <= currentPos ) {
|
|
||||||
defaultBlock = block;
|
|
||||||
if( defaultPosition < currentPos ) {
|
|
||||||
block++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for( int i = 0; i < positions.length; i++ ) {
|
|
||||||
if( positions[i] == currentPos ) {
|
|
||||||
writeLoadStore( true, tempI32 );
|
|
||||||
writeConstInt( keys[i] );
|
|
||||||
writeNumericOperator( NumericOperator.eq, ValueType.i32 );
|
|
||||||
writeBlockCode( WasmBlockOperator.BR_IF, block );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
block++;
|
|
||||||
} while( true );
|
|
||||||
if( defaultBlock < 0) {
|
|
||||||
defaultBlock = block;
|
|
||||||
}
|
|
||||||
writeBlockCode( WasmBlockOperator.BR, defaultBlock );
|
|
||||||
} else {
|
|
||||||
int low = byteCode.readInt();
|
|
||||||
int count = byteCode.readInt() - low + 1;
|
|
||||||
for( int i = 0; i < count; i++ ) {
|
|
||||||
byteCode.readInt();
|
|
||||||
}
|
|
||||||
if( low != 0 ) { // the br_table starts ever with the value 0. That we need to subtract the start value if it different
|
|
||||||
writeConstInt( low );
|
|
||||||
writeNumericOperator( NumericOperator.sub, ValueType.i32 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 172: // ireturn
|
case 172: // ireturn
|
||||||
case 173: // lreturn
|
case 173: // lreturn
|
||||||
@ -915,6 +856,88 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the both switch operation codes
|
||||||
|
*
|
||||||
|
* @param byteCode
|
||||||
|
* the current stream with a position after the operation code
|
||||||
|
* @param isLookupSwitch
|
||||||
|
* true, if the operation was a loopupswitch; false, if the operation was a tableswitch
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) throws IOException {
|
||||||
|
int startPosition = byteCode.getCodePosition();
|
||||||
|
int padding = startPosition % 4;
|
||||||
|
if( padding > 0 ) {
|
||||||
|
byteCode.skip( 4 - padding );
|
||||||
|
}
|
||||||
|
startPosition--;
|
||||||
|
|
||||||
|
int defaultPosition = byteCode.readInt();
|
||||||
|
if( isLookupSwitch ) { // lookupswitch
|
||||||
|
int count = byteCode.readInt();
|
||||||
|
int[] keys = new int[count];
|
||||||
|
int[] positions = new int[count];
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
keys[i] = byteCode.readInt();
|
||||||
|
positions[i] = byteCode.readInt();
|
||||||
|
}
|
||||||
|
int tempI32 = localVariables.getTempI32();
|
||||||
|
int block = 0;
|
||||||
|
int defaultBlock = -1;
|
||||||
|
int currentPos = -1;
|
||||||
|
writeLoadStore( false, tempI32 );
|
||||||
|
do {
|
||||||
|
int nextPos = findNext( currentPos, positions );
|
||||||
|
if( nextPos == currentPos ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentPos = nextPos;
|
||||||
|
if( defaultBlock < 0 ) {
|
||||||
|
if( defaultPosition <= currentPos ) {
|
||||||
|
defaultBlock = block;
|
||||||
|
if( defaultPosition < currentPos ) {
|
||||||
|
block++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( int i = 0; i < positions.length; i++ ) {
|
||||||
|
if( positions[i] == currentPos ) {
|
||||||
|
writeLoadStore( true, tempI32 );
|
||||||
|
writeConstInt( keys[i] );
|
||||||
|
writeNumericOperator( NumericOperator.eq, ValueType.i32 );
|
||||||
|
writeBlockCode( WasmBlockOperator.BR_IF, block );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
block++;
|
||||||
|
} while( true );
|
||||||
|
if( defaultBlock < 0 ) {
|
||||||
|
defaultBlock = block;
|
||||||
|
}
|
||||||
|
writeBlockCode( WasmBlockOperator.BR, defaultBlock );
|
||||||
|
} else {
|
||||||
|
int low = byteCode.readInt();
|
||||||
|
int count = byteCode.readInt() - low + 1;
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
byteCode.readInt();
|
||||||
|
}
|
||||||
|
if( low != 0 ) { // the br_table starts ever with the value 0. That we need to subtract the start value if it different
|
||||||
|
writeConstInt( low );
|
||||||
|
writeNumericOperator( NumericOperator.sub, ValueType.i32 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the next higher value.
|
||||||
|
*
|
||||||
|
* @param current
|
||||||
|
* the current value
|
||||||
|
* @param values
|
||||||
|
* the unordered list of values
|
||||||
|
* @return the next value or current value if not found.
|
||||||
|
*/
|
||||||
private static int findNext( int current, int[] values ) {
|
private static int findNext( int current, int[] values ) {
|
||||||
boolean find = false;
|
boolean find = false;
|
||||||
int next = Integer.MAX_VALUE;
|
int next = Integer.MAX_VALUE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user