skip ELSE blocks on counting the stack

This commit is contained in:
Volker Berlin 2019-09-29 13:47:45 +02:00
parent 4f40976019
commit ec898cad71

View File

@ -1054,18 +1054,13 @@ class BranchManger {
if( startBlock != null && startBlock.getOperation() == WasmBlockOperator.IF ) {
ArrayDeque<AnyType> stack = new ArrayDeque<>();
stack.push( ValueType.empty );
INSTRUCTIONS:
for( int i = startIdx; i < instructions.size(); i++ ) {
WasmInstruction instr = instructions.get( i );
int codePos = instr.getCodePosition();
if( codePos >= endPos ) {
break;
}
if( instr.getType() == Type.Block && ((WasmBlockInstruction)instr).getOperation() == WasmBlockOperator.RETURN ) {
while( stack.size() > 1 ) {
stack.pop();
}
break;
}
int popCount = instr.getPopCount();
for( int p = 0; p < popCount; p++ ) {
stack.pop();
@ -1074,10 +1069,59 @@ class BranchManger {
if( pushValue != null ) {
stack.push( pushValue );
}
if( instr.getType() == Type.Block ) {
switch( ((WasmBlockInstruction)instr).getOperation() ) {
case RETURN:
// set "empty" block type
while( stack.size() > 1 ) {
stack.pop();
}
break INSTRUCTIONS;
case IF:
case BLOCK:
case LOOP:
// skip the content of the block, important to not count ELSE blocks
i = findEndInstruction( instructions, i );
break;
}
}
}
startBlock.setData( stack.pop() );
}
}
/**
* Find the END instruction of the block.
*
* @param instructions
* the list of instructions
* @param idx
* the index of the block start
* @return the END index
*/
private int findEndInstruction( List<WasmInstruction> instructions, int idx ) {
int count = 0;
for( ; idx < instructions.size(); idx++ ) {
WasmInstruction instr = instructions.get( idx );
if( instr.getType() == Type.Block ) {
switch( ((WasmBlockInstruction)instr).getOperation() ) {
case IF:
case BLOCK:
case LOOP:
count++;
break;
case END:
count--;
break;
}
}
if( count == 0 ) {
break;
}
}
return idx;
}
}
/**