add branch operation after the creating the in memory model and not on

parsing.
This commit is contained in:
Volker 2018-07-15 18:06:25 +02:00
parent 949e3d2aa2
commit bab58acebe
2 changed files with 26 additions and 13 deletions

View File

@ -16,7 +16,6 @@
*/ */
package de.inetsoftware.jwebassembly.module; package de.inetsoftware.jwebassembly.module;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -441,7 +440,17 @@ class BranchManger {
* the byte code stream * the byte code stream
*/ */
void handle( CodeInputStream byteCode ) { void handle( CodeInputStream byteCode ) {
root.handle( byteCode.getCodePosition(), instructions ); int codePosition = -1;
for( int idx = 0; idx < instructions.size(); idx++ ) {
int nextCodePosition = instructions.get( idx ).getCodePosition();
if( nextCodePosition <= codePosition ) {
continue;
} else {
codePosition = nextCodePosition;
}
idx = root.handle( codePosition, instructions, idx );
}
root.handle( byteCode.getCodePosition(), instructions, instructions.size() );
} }
/** /**
@ -549,24 +558,28 @@ class BranchManger {
/** /**
* Handle branches on the current codePosition * Handle branches on the current codePosition
* *
* @param codePositions * @param codePosition
* current code position * current code position
* @param instructions * @param instructions
* the target for instructions * the target for instructions
* @param idx
* index in the current instruction
* @return the new index in the instructions
*/ */
void handle( int codePositions, List<WasmInstruction> instructions ) { int handle( int codePosition, List<WasmInstruction> instructions, int idx ) {
if( codePositions < startPos || codePositions > endPos ) { if( codePosition < startPos || codePosition > endPos ) {
return; return idx;
} }
if( codePositions == startPos && startOp != null ) { if( codePosition == startPos && startOp != null ) {
instructions.add( new WasmBlockInstruction( startOp, data, codePositions ) ); instructions.add( idx++, new WasmBlockInstruction( startOp, data, codePosition ) );
} }
for( BranchNode branch : this ) { for( BranchNode branch : this ) {
branch.handle( codePositions, instructions ); idx = branch.handle( codePosition, instructions, idx );
}
if( codePositions == endPos && endOp != null ) {
instructions.add( new WasmBlockInstruction( endOp, null, codePositions ) );
} }
if( codePosition == endPos && endOp != null ) {
instructions.add( idx++, new WasmBlockInstruction( endOp, null, codePosition ) );
}
return idx;
} }
} }
} }

View File

@ -530,7 +530,6 @@ public class ModuleGenerator {
while( byteCode.available() > 0 ) { while( byteCode.available() > 0 ) {
WasmInstruction instr = null; WasmInstruction instr = null;
int codePos = byteCode.getCodePosition(); int codePos = byteCode.getCodePosition();
branchManager.handle( byteCode );
endWithReturn = false; endWithReturn = false;
int op = byteCode.readUnsignedByte(); int op = byteCode.readUnsignedByte();
switch( op ) { switch( op ) {
@ -879,6 +878,7 @@ public class ModuleGenerator {
//TODO case 165: // if_acmpeq //TODO case 165: // if_acmpeq
//TODO case 166: // if_acmpne //TODO case 166: // if_acmpne
case 167: // goto case 167: // goto
instr = new WasmNopInstruction( codePos ); // marker of the line number for the branch manager
byteCode.skip(2); // handle in the branch manager byteCode.skip(2); // handle in the branch manager
break; break;
case 170: // tableswitch case 170: // tableswitch
@ -905,7 +905,7 @@ public class ModuleGenerator {
instructions.add( instr ); instructions.add( instr );
} }
} }
branchManager.handle( byteCode ); // write the last end operators branchManager.handle( byteCode ); // add branch operations
if( !endWithReturn && returnType != null ) { if( !endWithReturn && returnType != null ) {
// if a method ends with a loop without a break then code after the loop is no reachable // if a method ends with a loop without a break then code after the loop is no reachable
// Java does not need a return byte code in this case // Java does not need a return byte code in this case