add support for SWICH of strings

This commit is contained in:
Volker Berlin 2020-03-05 21:31:15 +01:00
parent a4040a8d3b
commit 6923765683

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -589,30 +590,81 @@ class BranchManger {
switchCase.block = blockCount; switchCase.block = blockCount;
} }
// handle the GOTO (breaks) at the end of the CASE blocks. // add extra blocks for forward GOTO jumps like in SWITCH of Strings
blockCount = 0; for( int p = 0; p < parsedOperations.size(); p++ ) {
BranchNode branch = blockNode; ParsedBlock parsedBlock = parsedOperations.get( p );
while( branch.size() > 0 ) { int start = parsedBlock.startPosition;
BranchNode node = branch.get( 0 ); if( startPosition >= lastPosition ) {
blockCount++; break;
}
for( int p = 0; p < parsedOperations.size(); p++ ) { if( parsedBlock.op != JavaBlockOperator.IF ) {
ParsedBlock parsedBlock = parsedOperations.get( p ); continue;
if( parsedBlock.startPosition < node.endPos ) { }
continue; int end = parsedBlock.endPosition;
} if( start < end ) {
if( parsedBlock.startPosition < lastPosition ) { BranchNode branch = blockNode;
if( parsedBlock.endPosition >= lastPosition && parsedBlock.op == JavaBlockOperator.GOTO ) { while( branch.size() > 0 /*&& start < branch.endPos*/ ) {
parsedOperations.remove( p ); BranchNode node = branch.get( 0 );
lastPosition = parsedBlock.endPosition; if( start > node.endPos ) {
branch.add( new BranchNode( parsedBlock.startPosition, parsedBlock.startPosition, WasmBlockOperator.BR, null, blockCount ) ); if( end > branch.endPos ) {
p--; BranchNode parentNode = branch;
while( end > parentNode.endPos ) {
parentNode = parentNode.parent;
}
BranchNode middleNode = new BranchNode( startPosition, parsedBlock.endPosition, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
BranchNode child = parentNode.remove( 0 );
parentNode.add( middleNode );
middleNode.add( child );
cases[posCount].block++;
}
break;
} }
} else { branch = node;
break;
} }
} }
branch = node; }
// handle the GOTO (breaks) at the end of the CASE blocks.
for( Iterator<ParsedBlock> it = parsedOperations.iterator(); it.hasNext(); ) {
ParsedBlock parsedBlock = it.next();
int start = parsedBlock.startPosition;
if( startPosition >= lastPosition ) {
break;
}
switch( parsedBlock.op ) {
case GOTO:
case IF:
int end = parsedBlock.endPosition;
if( start < end ) {
BranchNode branch = blockNode;
while( branch.size() > 0 ) {
BranchNode node = branch.get( 0 );
if( start > node.endPos ) {
if( end >= branch.endPos ) {
blockCount = 0;
BranchNode parentNode = branch;
while( parentNode != null && end > parentNode.endPos ) {
parentNode = parentNode.parent;
blockCount++;
}
WasmBlockOperator startOp;
if( parsedBlock.op == JavaBlockOperator.GOTO ) {
startOp = WasmBlockOperator.BR;
lastPosition = end;
} else {
startOp = WasmBlockOperator.BR_IF;
}
start++;
branch.add( new BranchNode( start, start, startOp, null, blockCount ) );
it.remove();
}
break;
}
branch = node;
}
}
}
} }
// Create the main block around the switch // Create the main block around the switch