mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
experimental exception handling
This commit is contained in:
parent
ce3e2d7546
commit
f15e9c8341
@ -749,6 +749,13 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
case UNREACHABLE:
|
||||
codeStream.writeOpCode( UNREACHABLE );
|
||||
break;
|
||||
case TRY:
|
||||
codeStream.writeOpCode( TRY );
|
||||
codeStream.write( ValueType.empty.getCode() ); // void; the return type of the try. currently we does not use it
|
||||
break;
|
||||
case CATCH:
|
||||
codeStream.writeOpCode( CATCH );
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown block: " + op );
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import de.inetsoftware.classparser.CodeInputStream;
|
||||
import de.inetsoftware.classparser.TryCatchFinally;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
|
||||
/**
|
||||
@ -57,10 +58,13 @@ class BranchManger {
|
||||
/**
|
||||
* Remove all branch information for reusing the manager.
|
||||
*/
|
||||
void reset() {
|
||||
void reset( TryCatchFinally[] exceptionTable ) {
|
||||
allParsedOperations.clear();
|
||||
root.clear();
|
||||
loops.clear();
|
||||
for( TryCatchFinally ex : exceptionTable ) {
|
||||
allParsedOperations.add( new TryCatchParsedBlock( ex ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,6 +228,9 @@ class BranchManger {
|
||||
case LOOP:
|
||||
calculateLoop( parent, parsedBlock, parsedOperations );
|
||||
break;
|
||||
case TRY:
|
||||
calculateTry( parent, (TryCatchParsedBlock)parsedBlock, parsedOperations );
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unimplemented block code operation: " + parsedBlock.op, null, null, parsedBlock.lineNumber );
|
||||
}
|
||||
@ -569,6 +576,35 @@ class BranchManger {
|
||||
// loopNode.add( new BranchNode( loopBlock.endPosition, loopBlock.endPosition, WasmBlockOperator.BR, null, 0 ) ); // continue to the start of the loop
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the needed nodes for try/catch
|
||||
* @param parent
|
||||
* the parent branch
|
||||
* @param tryBlock
|
||||
* the virtual TRY operation
|
||||
* @param parsedOperations
|
||||
* the not consumed operations in the parent branch
|
||||
*/
|
||||
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) {
|
||||
parsedOperations.remove( i );
|
||||
endPos = parsedBlock.endPosition;
|
||||
break;
|
||||
}
|
||||
if( parsedBlock.startPosition > gotoPos ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent.add( new BranchNode( tryBlock.startPosition, tryCatch.getHandler(), WasmBlockOperator.TRY, null ) );
|
||||
parent.add( new BranchNode( tryCatch.getHandler(), endPos, WasmBlockOperator.CATCH, WasmBlockOperator.END ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check on every instruction position if there any branch is ending
|
||||
*
|
||||
@ -682,6 +718,18 @@ class BranchManger {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of a parsed try-Catch structure.
|
||||
*/
|
||||
private static class TryCatchParsedBlock extends ParsedBlock {
|
||||
private final TryCatchFinally tryCatch;
|
||||
|
||||
TryCatchParsedBlock( TryCatchFinally tryCatch ) {
|
||||
super( JavaBlockOperator.TRY, tryCatch.getStart(), 0, -1 );
|
||||
this.tryCatch = tryCatch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Described a code branch/block node in a tree structure.
|
||||
*/
|
||||
|
@ -27,4 +27,5 @@ public enum JavaBlockOperator {
|
||||
GOTO,
|
||||
SWITCH,
|
||||
LOOP,
|
||||
TRY,
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ public class ModuleGenerator {
|
||||
writer.writeMethodStart( name );
|
||||
|
||||
localVariables.reset();
|
||||
branchManager.reset();
|
||||
branchManager.reset( code.getExceptionTable() );
|
||||
|
||||
byteCode = code.getByteCode();
|
||||
writeCode( byteCode, method.getConstantPool() );
|
||||
@ -388,10 +388,12 @@ public class ModuleGenerator {
|
||||
case 74: // dstore_3
|
||||
instr = loadStore( ValueType.f64, false, op - 71, codePos );
|
||||
break;
|
||||
//TODO case 75: // astore_0
|
||||
//TODO case 76: // astore_1
|
||||
//TODO case 77: // astore_2
|
||||
//TODO case 78: // astore_3
|
||||
case 75: // astore_0
|
||||
case 76: // astore_1
|
||||
case 77: // astore_2
|
||||
case 78: // astore_3
|
||||
instr = loadStore( ValueType.anyref, false, op - 75, codePos );
|
||||
break;
|
||||
//TODO case 79: // iastore
|
||||
//TODO case 80: // lastore
|
||||
//TODO case 81: // fastore
|
||||
|
@ -34,4 +34,6 @@ public enum WasmBlockOperator {
|
||||
BR_TABLE,
|
||||
LOOP,
|
||||
UNREACHABLE,
|
||||
TRY,
|
||||
CATCH,
|
||||
}
|
||||
|
@ -345,6 +345,15 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
case UNREACHABLE:
|
||||
name = "unreachable";
|
||||
break;
|
||||
case TRY:
|
||||
name = "try";
|
||||
insetAfter++;
|
||||
break;
|
||||
case CATCH:
|
||||
inset--;
|
||||
name = "catch";
|
||||
insetAfter++;
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown block: " + op );
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ public class WasmRule extends TemporaryFolder {
|
||||
* if the download failed
|
||||
*/
|
||||
private ProcessBuilder spiderMonkeyCommand() throws IOException {
|
||||
return new ProcessBuilder( spiderMonkey.getCommand(), spiderMonkeyScript.getAbsolutePath() );
|
||||
return new ProcessBuilder( spiderMonkey.getCommand(), "--wasm-gc", spiderMonkeyScript.getAbsolutePath() );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,7 +312,8 @@ public class WasmRule extends TemporaryFolder {
|
||||
command += "/bin/node";
|
||||
}
|
||||
}
|
||||
return new ProcessBuilder( command, "--experimental-wasm-se", "--experimental-wasm-sat-f2i-conversions", script.getAbsolutePath() );
|
||||
// details see with command: node --v8-options
|
||||
return new ProcessBuilder( command, "--experimental-wasm-se", "--experimental-wasm-sat-f2i-conversions", "--experimental-wasm-eh", "--experimental-wasm-anyref", script.getAbsolutePath() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ var wabt = require("wabt")();
|
||||
var filename = '{test.wat}';
|
||||
var text = nodeFS['readFileSync'](filename, "utf8");
|
||||
|
||||
var features = {'sat_float_to_int':true, 'sign_extension':true};
|
||||
var features = {'sat_float_to_int':true, 'sign_extension':true, 'exceptions':true};
|
||||
var ret = wabt.parseWat(filename, text, features);
|
||||
ret = ret.toBinary({}).buffer;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user