use for IF conditions also a block with input parameter to prevent problems with not splitable instruction like DUP (Java) or TEE (Wasm) #43

This commit is contained in:
Volker Berlin 2022-06-19 14:09:49 +02:00
parent 2b27364466
commit 47c28f7d46
No known key found for this signature in database
GPG Key ID: 988423EF815BE4CB
2 changed files with 6 additions and 44 deletions

View File

@ -531,39 +531,35 @@ class BranchManager {
private void calculateIf( BranchNode parent, IfParsedBlock startBlock, List<ParsedBlock> parsedOperations ) {
IfPositions positions = searchElsePosition( startBlock, parsedOperations );
BlockType conditionType = getConditionType();
BranchNode branch;
int endPos = positions.elsePos;
int startPos = startBlock.nextPosition - 1;
boolean createThenBlock = endPos <= parent.endPos;
if( createThenBlock ) {
// normal IF block
int startPos = startBlock.nextPosition;
if( startPos > endPos ) {
// the condition in a do while(condition) loop
int breakDeep = calculateContinueDeep( parent, endPos );
instructions.add( findIdxOfCodePos( startPos ), new WasmBlockInstruction( WasmBlockOperator.BR_IF, breakDeep, startPos - 1, startBlock.lineNumber ) );
instructions.add( findIdxOfCodePos( startPos + 1 ), new WasmBlockInstruction( WasmBlockOperator.BR_IF, breakDeep, startPos, startBlock.lineNumber ) );
return;
}
// find the code position where the condition values are push on the stack
List<WasmInstruction> instructions = this.instructions;
int idx = instructions.indexOf( startBlock.instr );
startPos = WasmCodeBuilder.findBlockStart( 1, instructions, idx + 1 );
if( parent.overlapped( startPos ) ) {
branch = addMiddleNode( parent, parent.startPos, endPos );
} else {
branch = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
branch = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END, conditionType );
parent.add( branch );
}
} else {
branch = parent;
// a jump outside of the parent, we will create the block later
}
breakOperations.add( new BreakBlock( WasmBlockOperator.BR_IF, branch, startBlock.nextPosition - 1, startBlock.endPosition ) );
breakOperations.add( new BreakBlock( WasmBlockOperator.BR_IF, branch, startPos, startBlock.endPosition ) );
for( int i = 0; i < positions.ifCount; i++ ) {
IfParsedBlock parsedBlock = (IfParsedBlock)parsedOperations.remove( 0 );
//instructions.remove( parsedBlock.jump );
breakOperations.add( new BreakBlock( WasmBlockOperator.BR_IF, branch, parsedBlock.nextPosition - 1, parsedBlock.endPosition ) );
}

View File

@ -15,7 +15,6 @@
*/
package de.inetsoftware.jwebassembly.module;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@ -156,39 +155,6 @@ public abstract class WasmCodeBuilder {
return false;
}
/**
* We need a value (or several) from the stack inside a block. We need to find the WasmInstruction where the block
* can can begin. If it is a function call or a numeric expression, it can be complicated to find the right point.
*
* @param count
* the count of values on the stack back. 1 means the last value. 2 means the penultimate value.
* @param instructions
* the instruction list for searching
* @param idx
* the start index for the search. Between 0 and instructions.size().
* @return the code position that push the last instruction
*/
static int findBlockStart( int count, List<WasmInstruction> instructions, int idx ) {
int valueCount = 0;
for( int i = idx - 1; i >= 0; i-- ) {
WasmInstruction instr = instructions.get( i );
AnyType valueType = instr.getPushValueType();
if( valueType != null ) {
valueCount++;
}
int popCount = instr.getPopCount();
valueCount -= popCount;
if( valueCount == count && popCount == 0 ) {
int codePos = instr.getCodePosition();
if( i == 0 || instructions.get( i - 1 ).getCodePosition() < codePos ) {
// if the same codePos is used from multiple instructions then it is not an atomic operation in Java
return codePos;
}
}
}
throw new WasmException( "Block start position not found", -1 ); // should never occur
}
/**
* We need the value type from the stack.
*
@ -210,7 +176,7 @@ public abstract class WasmCodeBuilder {
* the count of values on the stack back. 1 means the last value. 2 means the penultimate value.
* @param javaCodePos
* current code position for which the stack is inspected
* @return
* @return the type
*/
@Nonnull
AnyType findArrayTypeFromStack( int count, int javaCodePos ) {