mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
Use also RETURN in the BranchManager to calculate the IF THEN ELSE blocks.
This commit is contained in:
parent
7f9353833e
commit
9f0f82bb06
@ -100,7 +100,7 @@ class BranchManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Java block operator to handle from this manager.
|
||||
* Add a new GOTO operator to handle from this manager.
|
||||
*
|
||||
* @param startPosition
|
||||
* the byte position of the start position
|
||||
@ -115,6 +115,20 @@ class BranchManager {
|
||||
allParsedOperations.add( new ParsedBlock( JavaBlockOperator.GOTO, startPosition, offset, nextPosition, lineNumber ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new RETURN to help analyze structures.
|
||||
*
|
||||
* @param startPosition
|
||||
* the byte position of the start position
|
||||
* @param nextPosition
|
||||
* the position of the next instruction
|
||||
* @param lineNumber
|
||||
* the current line number
|
||||
*/
|
||||
void addReturnOperator( int startPosition, int nextPosition, int lineNumber ) {
|
||||
allParsedOperations.add( new ParsedBlock( JavaBlockOperator.RETURN, startPosition, 0, nextPosition, lineNumber ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new IF operator.
|
||||
*
|
||||
@ -375,6 +389,9 @@ class BranchManager {
|
||||
case TRY:
|
||||
calculateTry( parent, (TryCatchParsedBlock)parsedBlock, parsedOperations );
|
||||
break;
|
||||
case RETURN:
|
||||
// noting, only use as alternative GOTO
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unimplemented block code operation: " + parsedBlock.op, parsedBlock.lineNumber );
|
||||
}
|
||||
@ -462,35 +479,50 @@ class BranchManager {
|
||||
BranchNode branch = null;
|
||||
for( ; i < parsedOperations.size(); i++ ) {
|
||||
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||
if( parsedBlock.nextPosition == positions.elsePos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) {
|
||||
parsedOperations.remove( i );
|
||||
// end position can not be outside of the parent
|
||||
endPos = Math.min( parsedBlock.endPosition, parent.endPos );
|
||||
|
||||
branch = new BranchNode( startPos, positions.elsePos, WasmBlockOperator.IF, null );
|
||||
parent.add( branch );
|
||||
if( i > 0 ) {
|
||||
calculate( branch, parsedOperations.subList( 0, i ) );
|
||||
i = 0;
|
||||
if( parsedBlock.nextPosition == positions.elsePos ) {
|
||||
boolean endPosFound = false;
|
||||
if( parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) {
|
||||
parsedOperations.remove( i );
|
||||
endPos = parsedBlock.endPosition;
|
||||
endPosFound = true;
|
||||
} else if( parsedBlock.op == JavaBlockOperator.RETURN ) {
|
||||
for( int k = 0; k < i; k++ ) {
|
||||
ParsedBlock block = parsedOperations.get( k );
|
||||
if( block.op == JavaBlockOperator.IF ) {
|
||||
endPos = Math.max( endPos, block.endPosition );
|
||||
}
|
||||
}
|
||||
endPosFound = true;
|
||||
}
|
||||
if( endPosFound ) {
|
||||
// end position can not be outside of the parent
|
||||
endPos = Math.min( endPos, parent.endPos );
|
||||
|
||||
if( addBreakIfLoopContinue( branch, parsedBlock ) ) {
|
||||
branch.endOp = WasmBlockOperator.END;
|
||||
endPos = branch.endPos;
|
||||
branch = new BranchNode( startPos, positions.elsePos, WasmBlockOperator.IF, null );
|
||||
parent.add( branch );
|
||||
if( i > 0 ) {
|
||||
calculate( branch, parsedOperations.subList( 0, i ) );
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if( addBreakIfLoopContinue( branch, parsedBlock ) ) {
|
||||
branch.endOp = WasmBlockOperator.END;
|
||||
endPos = branch.endPos;
|
||||
break;
|
||||
}
|
||||
// if with block type signature must have an else block
|
||||
int breakDeep = calculateBreakDeep( parent, endPos );
|
||||
if( breakDeep > 0 ) {
|
||||
branch.endOp = WasmBlockOperator.END;
|
||||
branch.add( new BranchNode( positions.elsePos, endPos, WasmBlockOperator.BR, null, breakDeep + 1 ) );
|
||||
endPos = branch.endPos;
|
||||
} else {
|
||||
branch.elseEndPos = endPos;
|
||||
branch = new BranchNode( positions.elsePos, endPos, WasmBlockOperator.ELSE, WasmBlockOperator.END );
|
||||
parent.add( branch );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if with block type signature must have an else block
|
||||
int breakDeep = calculateBreakDeep( parent, endPos );
|
||||
if( breakDeep > 0 ) {
|
||||
branch.endOp = WasmBlockOperator.END;
|
||||
branch.add( new BranchNode( positions.elsePos, endPos, WasmBlockOperator.BR, null, breakDeep + 1 ) );
|
||||
endPos = branch.endPos;
|
||||
} else {
|
||||
branch.elseEndPos = endPos;
|
||||
branch = new BranchNode( positions.elsePos, endPos, WasmBlockOperator.ELSE, WasmBlockOperator.END );
|
||||
parent.add( branch );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( parsedBlock.nextPosition >= positions.elsePos ) {
|
||||
break;
|
||||
@ -562,10 +594,18 @@ class BranchManager {
|
||||
newElsePositionFound = false;
|
||||
for( int j = i; j < parsedOpCount; j++ ) {
|
||||
parsedBlock = parsedOperations.get( j );
|
||||
if( parsedBlock.op == JavaBlockOperator.GOTO ) {
|
||||
if( parsedBlock.nextPosition == endElse ) {
|
||||
break LOOP;
|
||||
}
|
||||
switch( parsedBlock.op ) {
|
||||
case IF:
|
||||
break;
|
||||
case GOTO:
|
||||
if( parsedBlock.nextPosition == endElse ) {
|
||||
break LOOP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( parsedBlock.nextPosition < endElse ) {
|
||||
break LOOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 Volker Berlin (i-net software)
|
||||
Copyright 2018 - 2022 Volker Berlin (i-net software)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -28,4 +28,5 @@ public enum JavaBlockOperator {
|
||||
SWITCH,
|
||||
LOOP,
|
||||
TRY,
|
||||
RETURN,
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018 - 2021 Volker Berlin (i-net software)
|
||||
* Copyright 2018 - 2022 Volker Berlin (i-net software)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -593,6 +593,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
type = null;
|
||||
}
|
||||
addBlockInstruction( WasmBlockOperator.RETURN, type, codePos, lineNumber );
|
||||
branchManager.addReturnOperator( codePos, byteCode.getCodePosition(), lineNumber );
|
||||
break;
|
||||
case 178: // getstatic
|
||||
ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
|
||||
|
@ -85,6 +85,11 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
addParam( list, script, "conditionalInsideIf_2" );
|
||||
addParam( list, script, "conditionalInsideIf_3" );
|
||||
addParam( list, script, "conditionalInsideIf_4" );
|
||||
addParam( list, script, "ifWithReturn8" );
|
||||
addParam( list, script, "ifWithReturn17" );
|
||||
addParam( list, script, "ifWithReturn21" );
|
||||
addParam( list, script, "ifWithReturn27" );
|
||||
addParam( list, script, "ifWithReturn28" );
|
||||
addParam( list, script, "stringSwitchNormalFoo" );
|
||||
addParam( list, script, "stringSwitchNormalBar" );
|
||||
addParam( list, script, "stringSwitchNormalDefault" );
|
||||
@ -684,6 +689,50 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifWithReturn8() {
|
||||
return ifWithReturn( 8, 0 );
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifWithReturn17() {
|
||||
return ifWithReturn( 8, 13 );
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifWithReturn21() {
|
||||
return ifWithReturn( 8, 5 );
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifWithReturn27() {
|
||||
return ifWithReturn( 0, 0 );
|
||||
}
|
||||
|
||||
@Export
|
||||
static int ifWithReturn28() {
|
||||
return ifWithReturn( 0, 1 );
|
||||
}
|
||||
|
||||
private static int ifWithReturn( int a, int b ) {
|
||||
if( a > 7 ) {
|
||||
if( b > 1 ) {
|
||||
if( b == 13 ) {
|
||||
return 17;
|
||||
} else {
|
||||
return 21;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( a == b ) {
|
||||
return 27;
|
||||
} else {
|
||||
return 28;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
@Export
|
||||
static int stringSwitchNormalFoo() {
|
||||
return stringSwitchNormal( "foo" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user