mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Use the normal break handling for the GOTO in the CASEs of an SWITCH. This eliminates the need to calculate the end of the SWITCH structure. #43
This commit is contained in:
parent
c392afc76f
commit
442e0c896c
@ -940,55 +940,7 @@ class BranchManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the GOTO (breaks) at the end of the CASE blocks.
|
parent.add( blockNode );
|
||||||
int lastBlockPosition = lastPosition;
|
|
||||||
for( Iterator<ParsedBlock> it = parsedOperations.iterator(); it.hasNext(); ) {
|
|
||||||
ParsedBlock parsedBlock = it.next();
|
|
||||||
int start = parsedBlock.startPosition;
|
|
||||||
if( start >= lastBlockPosition ) {
|
|
||||||
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 = Math.max( lastPosition, end );
|
|
||||||
} else {
|
|
||||||
startOp = WasmBlockOperator.BR_IF;
|
|
||||||
instructions.remove( ((IfParsedBlock)parsedBlock).jump );
|
|
||||||
}
|
|
||||||
start++;
|
|
||||||
branch.add( new BranchNode( start, start, startOp, null, blockCount ) );
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
branch = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the main block around the switch
|
|
||||||
BranchNode switchNode = new BranchNode( startPosition, lastPosition, WasmBlockOperator.BLOCK, WasmBlockOperator.END, switchType );
|
|
||||||
switchNode.add( blockNode );
|
|
||||||
parent.add( switchNode );
|
|
||||||
|
|
||||||
if( brTableNode != null ) {
|
if( brTableNode != null ) {
|
||||||
// sort back in the natural order and create a br_table
|
// sort back in the natural order and create a br_table
|
||||||
@ -1000,11 +952,11 @@ class BranchManager {
|
|||||||
brTableNode.data = data;
|
brTableNode.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = 0; i < cases.length; i++ ) {
|
blockNode = cases[0].node;
|
||||||
switchCase = cases[i];
|
do {
|
||||||
calculateSubOperations( switchCase.node, parsedOperations );
|
calculateSubOperations( blockNode, parsedOperations );
|
||||||
}
|
blockNode = blockNode.parent;
|
||||||
calculateSubOperations( switchNode, parsedOperations );
|
} while( blockNode != parent );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1473,8 +1425,7 @@ class BranchManager {
|
|||||||
* @return the new node
|
* @return the new node
|
||||||
*/
|
*/
|
||||||
private BranchNode addMiddleNode( BranchNode parent, int startPos, int endPos ) {
|
private BranchNode addMiddleNode( BranchNode parent, int startPos, int endPos ) {
|
||||||
Object data = parent.data == switchType && parent.startPos == startPos ? switchType : null;
|
BranchNode middleNode = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
|
||||||
BranchNode middleNode = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END, data );
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for( Iterator<BranchNode> it = parent.iterator(); it.hasNext(); ) {
|
for( Iterator<BranchNode> it = parent.iterator(); it.hasNext(); ) {
|
||||||
BranchNode child = it.next();
|
BranchNode child = it.next();
|
||||||
@ -1488,8 +1439,18 @@ class BranchManager {
|
|||||||
middleNode.add( child );
|
middleNode.add( child );
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use same input parameter if parent or child start on same position
|
||||||
|
if( parent.startPos == startPos ) {
|
||||||
|
middleNode.data = parent.data;
|
||||||
|
} else if( middleNode.size() > 0 ) {
|
||||||
|
BranchNode child = middleNode.get( 0 );
|
||||||
|
if( child.startPos == startPos ) {
|
||||||
|
middleNode.data = child.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parent.add( idx, middleNode );
|
parent.add( idx, middleNode );
|
||||||
parent = middleNode;
|
|
||||||
patchBrDeep( middleNode );
|
patchBrDeep( middleNode );
|
||||||
return middleNode;
|
return middleNode;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
addParam( list, script, "ifCompare" );
|
addParam( list, script, "ifCompare" );
|
||||||
addParam( list, script, "switchDirect" );
|
addParam( list, script, "switchDirect" );
|
||||||
addParam( list, script, "switchWithConditionMethodParams" );
|
addParam( list, script, "switchWithConditionMethodParams" );
|
||||||
|
addParam( list, script, "switchWithConditionSelect" );
|
||||||
addParam( list, script, "endlessLoop" );
|
addParam( list, script, "endlessLoop" );
|
||||||
addParam( list, script, "doWhileLoop" );
|
addParam( list, script, "doWhileLoop" );
|
||||||
addParam( list, script, "doWhileLoopTwoConditions" );
|
addParam( list, script, "doWhileLoopTwoConditions" );
|
||||||
@ -303,6 +304,42 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
private static int switchWithConditionSelect() {
|
||||||
|
boolean cond = true;
|
||||||
|
int c1 = 1;
|
||||||
|
int c2 = 2;
|
||||||
|
int b;
|
||||||
|
switch( cond ? c1 : c2 ) {
|
||||||
|
case 1:
|
||||||
|
b = 17;
|
||||||
|
switch( cond ? c1 : c2 ) {
|
||||||
|
case 1:
|
||||||
|
b = 13;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
b = 14;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 1001:
|
||||||
|
if( c1 == 1000 ) {
|
||||||
|
b = 1000;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
b = 1001;
|
||||||
|
}
|
||||||
|
//$FALL-THROUGH$
|
||||||
|
case Integer.MAX_VALUE:
|
||||||
|
b = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
b = 9;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
@Export
|
@Export
|
||||||
static int endlessLoop() {
|
static int endlessLoop() {
|
||||||
int a = 0;
|
int a = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user