mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
expand a loop if there is a SWICH structure that point outside the loop. #43
This commit is contained in:
parent
47c28f7d46
commit
9d1c9ee93b
@ -154,8 +154,6 @@ class BranchManager {
|
|||||||
*
|
*
|
||||||
* @param startPosition
|
* @param startPosition
|
||||||
* the byte position of the start position
|
* the byte position of the start position
|
||||||
* @param offset
|
|
||||||
* the relative jump position
|
|
||||||
* @param lineNumber
|
* @param lineNumber
|
||||||
* the current line number
|
* the current line number
|
||||||
* @param keys
|
* @param keys
|
||||||
@ -165,8 +163,8 @@ class BranchManager {
|
|||||||
* @param defaultPosition
|
* @param defaultPosition
|
||||||
* the code position of the default block
|
* the code position of the default block
|
||||||
*/
|
*/
|
||||||
void addSwitchOperator( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) {
|
void addSwitchOperator( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
|
||||||
allParsedOperations.add( new SwitchParsedBlock( startPosition, offset, lineNumber, keys, positions, defaultPosition ) );
|
allParsedOperations.add( new SwitchParsedBlock( startPosition, lineNumber, keys, positions, defaultPosition ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,6 +222,7 @@ class BranchManager {
|
|||||||
if( loop.endPosition < parsedBlock.nextPosition ) {
|
if( loop.endPosition < parsedBlock.nextPosition ) {
|
||||||
int nextPosition = parsedBlock.startPosition; // Jump position for Continue
|
int nextPosition = parsedBlock.startPosition; // Jump position for Continue
|
||||||
int endPosition = parsedBlock.nextPosition;
|
int endPosition = parsedBlock.nextPosition;
|
||||||
|
|
||||||
// if a condition behind the loop points to a position inside the loop, the loop must be extended to avoid overlapping blocks.
|
// if a condition behind the loop points to a position inside the loop, the loop must be extended to avoid overlapping blocks.
|
||||||
for( int n = b + 1; n < parsedOperations.size(); n++ ) {
|
for( int n = b + 1; n < parsedOperations.size(); n++ ) {
|
||||||
ParsedBlock block = parsedOperations.get( n );
|
ParsedBlock block = parsedOperations.get( n );
|
||||||
@ -232,6 +231,21 @@ class BranchManager {
|
|||||||
endPosition = block.nextPosition;
|
endPosition = block.nextPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there is a structure like a SWITCH that overlap the loop then we must be extended the loop to avoid this.
|
||||||
|
for( int n = b - 1; n >= 0; n-- ) {
|
||||||
|
ParsedBlock prevBlock = parsedOperations.get( n );
|
||||||
|
switch( prevBlock.op ) {
|
||||||
|
case SWITCH:
|
||||||
|
if( start < prevBlock.startPosition && prevBlock.endPosition > endPosition ) {
|
||||||
|
nextPosition = prevBlock.endPosition;
|
||||||
|
endPosition = nextPosition;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loop.nextPosition = nextPosition; // Jump position for Continue
|
loop.nextPosition = nextPosition; // Jump position for Continue
|
||||||
loop.endPosition = endPosition;
|
loop.endPosition = endPosition;
|
||||||
}
|
}
|
||||||
@ -1600,11 +1614,18 @@ class BranchManager {
|
|||||||
|
|
||||||
private int defaultPosition;
|
private int defaultPosition;
|
||||||
|
|
||||||
public SwitchParsedBlock( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) {
|
public SwitchParsedBlock( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
|
||||||
super( JavaBlockOperator.SWITCH, startPosition, offset, startPosition, lineNumber );
|
super( JavaBlockOperator.SWITCH, startPosition, 0, startPosition, lineNumber );
|
||||||
this.keys = keys;
|
this.keys = keys;
|
||||||
this.positions = positions;
|
this.positions = positions;
|
||||||
this.defaultPosition = defaultPosition;
|
this.defaultPosition = defaultPosition;
|
||||||
|
|
||||||
|
// calculate the end position of the switch
|
||||||
|
int end = defaultPosition;
|
||||||
|
for( int i = positions.length - 1; i >= 0; i-- ) {
|
||||||
|
end = Math.max( defaultPosition, positions[i] );
|
||||||
|
}
|
||||||
|
this.endPosition = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +845,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
|
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
branchManager.addSwitchOperator( startPosition, 0, lineNumber, keys, positions, defaultPosition );
|
branchManager.addSwitchOperator( startPosition, lineNumber, keys, positions, defaultPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,6 +60,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
addParam( list, script, "whileLoopAfterIfWithReturn" );
|
addParam( list, script, "whileLoopAfterIfWithReturn" );
|
||||||
addParam( list, script, "whileLoopInsideLoop" );
|
addParam( list, script, "whileLoopInsideLoop" );
|
||||||
addParam( list, script, "whileTrueInsideWhileTrue" );
|
addParam( list, script, "whileTrueInsideWhileTrue" );
|
||||||
|
addParam( list, script, "whileTrueContinueWithSwitch" );
|
||||||
addParam( list, script, "forLoop" );
|
addParam( list, script, "forLoop" );
|
||||||
addParam( list, script, "conditionalOperator" );
|
addParam( list, script, "conditionalOperator" );
|
||||||
addParam( list, script, "conditionalOperator2" );
|
addParam( list, script, "conditionalOperator2" );
|
||||||
@ -510,6 +511,25 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
return sw;
|
return sw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int whileTrueContinueWithSwitch() {
|
||||||
|
int sw = 1;
|
||||||
|
LOOP:
|
||||||
|
while( true ) {
|
||||||
|
switch(sw) {
|
||||||
|
case 1:
|
||||||
|
sw++;
|
||||||
|
continue LOOP;
|
||||||
|
case 5:
|
||||||
|
return sw;
|
||||||
|
default:
|
||||||
|
sw++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sw;
|
||||||
|
}
|
||||||
|
|
||||||
@Export
|
@Export
|
||||||
static int forLoop() {
|
static int forLoop() {
|
||||||
int a = 0;
|
int a = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user