mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 18:44:47 +01:00
improve the compiling of exceptions
This commit is contained in:
parent
b9bbb1c56d
commit
cd2f07733d
@ -847,7 +847,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
break;
|
||||
case BLOCK:
|
||||
codeStream.writeOpCode( BLOCK );
|
||||
codeStream.writeValueType( ValueType.empty ); // void; the return type of the block. currently we does not use it
|
||||
codeStream.writeValueType( data == null ? ValueType.empty : (ValueType)data ); // void; the return type of the block.
|
||||
break;
|
||||
case BR:
|
||||
codeStream.writeOpCode( BR );
|
||||
@ -879,6 +879,18 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
case CATCH:
|
||||
codeStream.writeOpCode( CATCH );
|
||||
break;
|
||||
case THROW:
|
||||
codeStream.writeOpCode( THROW );
|
||||
codeStream.writeVaruint32( 0 ); // event/exception ever 0 because currently there is only one with signature anyref
|
||||
break;
|
||||
case RETHROW:
|
||||
codeStream.writeOpCode( RETHROW );
|
||||
break;
|
||||
case BR_ON_EXN:
|
||||
codeStream.writeOpCode( BR_ON_EXN );
|
||||
codeStream.writeVaruint32( (Integer)data ); // break depth
|
||||
codeStream.writeVaruint32( 0 ); // event/exception ever 0 because currently there is only one with signature anyref
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown block: " + op );
|
||||
}
|
||||
|
@ -48,7 +48,9 @@ class BranchManger {
|
||||
|
||||
private final HashMap<Integer, ParsedBlock> loops = new HashMap<>();
|
||||
|
||||
private final List<WasmInstruction> instructions;
|
||||
private final List<WasmInstruction> instructions;
|
||||
|
||||
private TryCatchFinally[] exceptionTable;
|
||||
|
||||
/**
|
||||
* Create a branch manager.
|
||||
@ -71,7 +73,7 @@ class BranchManger {
|
||||
root.clear();
|
||||
loops.clear();
|
||||
root.endPos = code.getCodeSize();
|
||||
TryCatchFinally[] exceptionTable = code.getExceptionTable();
|
||||
exceptionTable = code.getExceptionTable();
|
||||
for( TryCatchFinally ex : exceptionTable ) {
|
||||
allParsedOperations.add( new TryCatchParsedBlock( ex ) );
|
||||
}
|
||||
@ -588,6 +590,36 @@ class BranchManger {
|
||||
|
||||
/**
|
||||
* Calculate the needed nodes for try/catch
|
||||
* Sample: The follow Java code:
|
||||
*
|
||||
* <pre>
|
||||
* try {
|
||||
* code1
|
||||
* catch(Exception ex)
|
||||
* code2
|
||||
* }
|
||||
* code3
|
||||
* </pre>
|
||||
*
|
||||
* Should be converted to the follow Wasm code for tableswitch:
|
||||
*
|
||||
* <pre>
|
||||
* block
|
||||
* block (result anyref)
|
||||
* try
|
||||
* code1
|
||||
* catch
|
||||
* br_on_exn 1 0
|
||||
* rethrow
|
||||
* end
|
||||
* br 1
|
||||
* end
|
||||
* local.set x
|
||||
* code2
|
||||
* end
|
||||
* code3
|
||||
* </pre>
|
||||
*
|
||||
* @param parent
|
||||
* the parent branch
|
||||
* @param tryBlock
|
||||
@ -595,14 +627,14 @@ class BranchManger {
|
||||
* @param parsedOperations
|
||||
* the not consumed operations in the parent branch
|
||||
*/
|
||||
private void calculateTry ( BranchNode parent, TryCatchParsedBlock tryBlock, List<ParsedBlock> parsedOperations ) {
|
||||
private void calculateTry( BranchNode parent, TryCatchParsedBlock tryBlock, List<ParsedBlock> parsedOperations ) {
|
||||
TryCatchFinally tryCatch = tryBlock.tryCatch;
|
||||
|
||||
int gotoPos = tryCatch.getEnd(); // alternativ we can use tryCatch.getHandler()-3
|
||||
int endPos = parent.endPos;
|
||||
for( int i = 0; i < parsedOperations.size(); i++ ) {
|
||||
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||
if( parsedBlock.startPosition == gotoPos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition) {
|
||||
if( parsedBlock.startPosition == gotoPos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) {
|
||||
parsedOperations.remove( i );
|
||||
endPos = parsedBlock.endPosition;
|
||||
break;
|
||||
@ -611,8 +643,40 @@ class BranchManger {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent.add( new BranchNode( tryBlock.startPosition, tryCatch.getHandler(), WasmBlockOperator.TRY, null ) );
|
||||
parent.add( new BranchNode( tryCatch.getHandler(), endPos, WasmBlockOperator.CATCH, WasmBlockOperator.END ) );
|
||||
int startPos = tryBlock.startPosition;
|
||||
int catchPos = tryCatch.getHandler();
|
||||
BranchNode node = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
|
||||
parent.add( node );
|
||||
parent = node;
|
||||
|
||||
node = new BranchNode( startPos, catchPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END, ValueType.anyref );
|
||||
parent.add( node );
|
||||
parent = node;
|
||||
|
||||
parent.add( new BranchNode( startPos, catchPos, WasmBlockOperator.TRY, null ) );
|
||||
BranchNode catchNode = new BranchNode( catchPos, catchPos, WasmBlockOperator.CATCH, WasmBlockOperator.END );
|
||||
parent.add( catchNode );
|
||||
|
||||
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR_ON_EXN, null, 1 ) );
|
||||
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.RETHROW, null ) );
|
||||
|
||||
parent.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR, null, 1 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are a start of a catch block on the code position.
|
||||
*
|
||||
* @param codePosition
|
||||
* the code position
|
||||
* @return true, if there is a catch block
|
||||
*/
|
||||
boolean isCatch( int codePosition ) {
|
||||
for( TryCatchFinally tryCatch : exceptionTable ) {
|
||||
if( tryCatch.getHandler() == codePosition ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +241,11 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 76: // astore_1
|
||||
case 77: // astore_2
|
||||
case 78: // astore_3
|
||||
storeType = findPreviousPushInstructionPushValueType();
|
||||
if( branchManager.isCatch( codePos ) ) {
|
||||
storeType = ValueType.anyref; // for the catch there are no previous instructions
|
||||
} else {
|
||||
storeType = findPreviousPushInstructionPushValueType();
|
||||
}
|
||||
addLoadStoreInstruction( storeType, false, op - 75, codePos );
|
||||
break;
|
||||
case 79: // iastore
|
||||
@ -556,7 +560,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
|
||||
addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos );
|
||||
break;
|
||||
//TODO case 182: // invokevirtual
|
||||
case 182: // invokevirtual
|
||||
case 183: // invokespecial, invoke a constructor
|
||||
case 184: // invokestatic
|
||||
idx = byteCode.readUnsignedShort();
|
||||
@ -603,7 +607,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 190: // arraylength
|
||||
addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos );
|
||||
break;
|
||||
//TODO case 191: // athrow
|
||||
case 191: // athrow
|
||||
addBlockInstruction( WasmBlockOperator.THROW, null, codePos );
|
||||
break;
|
||||
//TODO case 192: // checkcast
|
||||
//TODO case 193: // instanceof
|
||||
//TODO case 194: // monitorenter
|
||||
|
@ -389,6 +389,9 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
break;
|
||||
case BLOCK:
|
||||
name = "block";
|
||||
if( data != null ) {
|
||||
name += " (result " + data + ")";
|
||||
}
|
||||
insetAfter++;
|
||||
break;
|
||||
case BR:
|
||||
@ -420,6 +423,15 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
name = "catch";
|
||||
insetAfter++;
|
||||
break;
|
||||
case THROW:
|
||||
name = "throw 0"; // currently there is only one event/exception with anyref
|
||||
break;
|
||||
case RETHROW:
|
||||
name = "rethrow";
|
||||
break;
|
||||
case BR_ON_EXN:
|
||||
name = "br_on_exn " + data + " 0"; // br_on_exn, break depth, event; // currently there is only one event/exception with anyref
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown block: " + op );
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 Volker Berlin (i-net software)
|
||||
Copyright 2018 - 2019 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.
|
||||
@ -36,4 +36,7 @@ public enum WasmBlockOperator {
|
||||
UNREACHABLE,
|
||||
TRY,
|
||||
CATCH,
|
||||
THROW,
|
||||
RETHROW,
|
||||
BR_ON_EXN,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user