Skip to content

Commit

Permalink
Use the normal break handling for the GOTO in the CASEs of an SWITCH.…
Browse files Browse the repository at this point in the history
… This eliminates the need to calculate the end of the SWITCH structure. #43
  • Loading branch information
Horcrux7 committed Jun 6, 2022
1 parent c392afc commit 442e0c8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 57 deletions.
75 changes: 18 additions & 57 deletions src/de/inetsoftware/jwebassembly/module/BranchManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -940,55 +940,7 @@ private void calculateSwitch( BranchNode parent, SwitchParsedBlock switchBlock,
}
}

// handle the GOTO (breaks) at the end of the CASE blocks.
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 );
parent.add( blockNode );

if( brTableNode != null ) {
// sort back in the natural order and create a br_table
Expand All @@ -1000,11 +952,11 @@ private void calculateSwitch( BranchNode parent, SwitchParsedBlock switchBlock,
brTableNode.data = data;
}

for( int i = 0; i < cases.length; i++ ) {
switchCase = cases[i];
calculateSubOperations( switchCase.node, parsedOperations );
}
calculateSubOperations( switchNode, parsedOperations );
blockNode = cases[0].node;
do {
calculateSubOperations( blockNode, parsedOperations );
blockNode = blockNode.parent;
} while( blockNode != parent );
}

/**
Expand Down Expand Up @@ -1473,8 +1425,7 @@ private void calculateBreak( BreakBlock breakBlock ) {
* @return the new node
*/
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, data );
BranchNode middleNode = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
int idx = 0;
for( Iterator<BranchNode> it = parent.iterator(); it.hasNext(); ) {
BranchNode child = it.next();
Expand All @@ -1488,8 +1439,18 @@ private BranchNode addMiddleNode( BranchNode parent, int startPos, int endPos )
middleNode.add( child );
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 = middleNode;
patchBrDeep( middleNode );
return middleNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static Collection<Object[]> data() {
addParam( list, script, "ifCompare" );
addParam( list, script, "switchDirect" );
addParam( list, script, "switchWithConditionMethodParams" );
addParam( list, script, "switchWithConditionSelect" );
addParam( list, script, "endlessLoop" );
addParam( list, script, "doWhileLoop" );
addParam( list, script, "doWhileLoopTwoConditions" );
Expand Down Expand Up @@ -303,6 +304,42 @@ public static int switchWithConditionMethodParams() {
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
static int endlessLoop() {
int a = 0;
Expand Down

0 comments on commit 442e0c8

Please sign in to comment.