mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
Simplify the try/catch structure
This commit is contained in:
parent
5a665b7c11
commit
87359fb497
@ -66,7 +66,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
|
|
||||||
private final boolean createSourceMap;
|
private final boolean createSourceMap;
|
||||||
|
|
||||||
private WasmOutputStream codeStream = new WasmOutputStream();
|
private WasmOutputStream codeStream = new WasmOutputStream( options );
|
||||||
|
|
||||||
private List<TypeEntry> functionTypes = new ArrayList<>();
|
private List<TypeEntry> functionTypes = new ArrayList<>();
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
wasm = new WasmOutputStream( target.getWasmOutput() );
|
wasm = new WasmOutputStream( options, target.getWasmOutput() );
|
||||||
wasm.write( WASM_BINARY_MAGIC );
|
wasm.write( WASM_BINARY_MAGIC );
|
||||||
wasm.writeInt32( WASM_BINARY_VERSION );
|
wasm.writeInt32( WASM_BINARY_VERSION );
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
private void writeSection( SectionType type, Collection<? extends SectionEntry> entries ) throws IOException {
|
private void writeSection( SectionType type, Collection<? extends SectionEntry> entries ) throws IOException {
|
||||||
int count = entries.size();
|
int count = entries.size();
|
||||||
if( count > 0 ) {
|
if( count > 0 ) {
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( count );
|
stream.writeVaruint32( count );
|
||||||
for( SectionEntry entry : entries ) {
|
for( SectionEntry entry : entries ) {
|
||||||
entry.writeSectionEntry( stream );
|
entry.writeSectionEntry( stream );
|
||||||
@ -174,7 +174,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
int count = 1;
|
int count = 1;
|
||||||
if( stringCount > 0 ) {
|
if( stringCount > 0 ) {
|
||||||
count++;
|
count++;
|
||||||
@ -217,7 +217,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
private void writeMemorySection() throws IOException {
|
private void writeMemorySection() throws IOException {
|
||||||
int dataSize = dataStream.size();
|
int dataSize = dataStream.size();
|
||||||
if( dataSize > 0 ) {
|
if( dataSize > 0 ) {
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
int pages = (dataSize + 0xFFFF) / 0x10000; // a page is defined with a size of 64KiB
|
int pages = (dataSize + 0xFFFF) / 0x10000; // a page is defined with a size of 64KiB
|
||||||
int count = 1;
|
int count = 1;
|
||||||
stream.writeVaruint32( count );
|
stream.writeVaruint32( count );
|
||||||
@ -238,7 +238,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
*/
|
*/
|
||||||
private void writeEventSection() throws IOException {
|
private void writeEventSection() throws IOException {
|
||||||
if( exceptionSignatureIndex >= 0 ) {
|
if( exceptionSignatureIndex >= 0 ) {
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( 1 );
|
stream.writeVaruint32( 1 );
|
||||||
|
|
||||||
// event declaration
|
// event declaration
|
||||||
@ -260,7 +260,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int id = getFunction( startFunction ).id;
|
int id = getFunction( startFunction ).id;
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( id );
|
stream.writeVaruint32( id );
|
||||||
wasm.writeSection( SectionType.Start, stream );
|
wasm.writeSection( SectionType.Start, stream );
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
}
|
}
|
||||||
|
|
||||||
int elemCount = imports.size() + functions.size();
|
int elemCount = imports.size() + functions.size();
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( 1 ); // count of element segments to follow
|
stream.writeVaruint32( 1 ); // count of element segments to follow
|
||||||
|
|
||||||
// element_segment
|
// element_segment
|
||||||
@ -305,7 +305,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
}
|
}
|
||||||
|
|
||||||
int start = wasm.size();
|
int start = wasm.size();
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( size );
|
stream.writeVaruint32( size );
|
||||||
for( Entry<String, Function> entry : functions.entrySet() ) {
|
for( Entry<String, Function> entry : functions.entrySet() ) {
|
||||||
try {
|
try {
|
||||||
@ -345,7 +345,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeVaruint32( 1 ); // count, we use one large segment
|
stream.writeVaruint32( 1 ); // count, we use one large segment
|
||||||
|
|
||||||
// one data segment
|
// one data segment
|
||||||
@ -368,12 +368,12 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
if( !options.debugNames() ) {
|
if( !options.debugNames() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeString( "name" ); // Custom Section name "name", content is part of the section length
|
stream.writeString( "name" ); // Custom Section name "name", content is part of the section length
|
||||||
|
|
||||||
// write function names
|
// write function names
|
||||||
stream.write( 1 ); // 1 - Function name
|
stream.write( 1 ); // 1 - Function name
|
||||||
WasmOutputStream section = new WasmOutputStream();
|
WasmOutputStream section = new WasmOutputStream( options );
|
||||||
section.writeVaruint32( imports.size() + functions.size() );
|
section.writeVaruint32( imports.size() + functions.size() );
|
||||||
writeDebugFunctionNames( imports.entrySet(), section );
|
writeDebugFunctionNames( imports.entrySet(), section );
|
||||||
writeDebugFunctionNames( functions.entrySet(), section );
|
writeDebugFunctionNames( functions.entrySet(), section );
|
||||||
@ -449,7 +449,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
if( url == null ) {
|
if( url == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeString( "sourceMappingURL" ); // Custom Section name "sourceMappingURL", content is part of the section length
|
stream.writeString( "sourceMappingURL" ); // Custom Section name "sourceMappingURL", content is part of the section length
|
||||||
stream.writeString( url );
|
stream.writeString( url );
|
||||||
wasm.writeSection( SectionType.Custom, stream );
|
wasm.writeSection( SectionType.Custom, stream );
|
||||||
@ -465,7 +465,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
Package pack = getClass().getPackage();
|
Package pack = getClass().getPackage();
|
||||||
String version = pack == null ? null : pack.getImplementationVersion();
|
String version = pack == null ? null : pack.getImplementationVersion();
|
||||||
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream( options );
|
||||||
stream.writeString( "producers" ); // Custom Section name "producers", content is part of the section length
|
stream.writeString( "producers" ); // Custom Section name "producers", content is part of the section length
|
||||||
|
|
||||||
stream.writeVaruint32( 2 ); // field_count; number of fields that follow (language and processed-by)
|
stream.writeVaruint32( 2 ); // field_count; number of fields that follow (language and processed-by)
|
||||||
@ -511,13 +511,20 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
@Override
|
@Override
|
||||||
protected void writeException() throws IOException {
|
protected void writeException() throws IOException {
|
||||||
if( exceptionSignatureIndex <= 0 ) {
|
if( exceptionSignatureIndex <= 0 ) {
|
||||||
FunctionTypeEntry exceptionType = new FunctionTypeEntry();
|
FunctionTypeEntry type = new FunctionTypeEntry();
|
||||||
exceptionType.params.add( ValueType.anyref );
|
type.params.add( ValueType.anyref );
|
||||||
exceptionSignatureIndex = functionTypes.indexOf( exceptionType );
|
exceptionSignatureIndex = functionTypes.indexOf( type );
|
||||||
if( exceptionSignatureIndex < 0 ) {
|
if( exceptionSignatureIndex < 0 ) {
|
||||||
exceptionSignatureIndex = functionTypes.size();
|
exceptionSignatureIndex = functionTypes.size();
|
||||||
functionTypes.add( exceptionType );
|
functionTypes.add( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// result type of catch block for unboxing
|
||||||
|
type = new FunctionTypeEntry();
|
||||||
|
type.params.add( ValueType.exnref );
|
||||||
|
type.results.add( ValueType.anyref );
|
||||||
|
options.setCatchType( functionTypes.size() );
|
||||||
|
functionTypes.add( type );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,7 +646,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
@Override
|
@Override
|
||||||
protected void writeMethodFinish() throws IOException {
|
protected void writeMethodFinish() throws IOException {
|
||||||
@SuppressWarnings( "resource" )
|
@SuppressWarnings( "resource" )
|
||||||
WasmOutputStream localsTypeStream = new WasmOutputStream();
|
WasmOutputStream localsTypeStream = new WasmOutputStream( options );
|
||||||
int localEntryCount = 0; // number of local entries in output
|
int localEntryCount = 0; // number of local entries in output
|
||||||
int varCount = locals.size();
|
int varCount = locals.size();
|
||||||
for( int i = 0; i < varCount; ) {
|
for( int i = 0; i < varCount; ) {
|
||||||
@ -655,10 +662,10 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "resource" )
|
@SuppressWarnings( "resource" )
|
||||||
WasmOutputStream localsStream = new WasmOutputStream();
|
WasmOutputStream localsStream = new WasmOutputStream( options );
|
||||||
localsStream.writeVaruint32( localEntryCount );
|
localsStream.writeVaruint32( localEntryCount );
|
||||||
|
|
||||||
WasmOutputStream functionsStream = function.functionsStream = new WasmOutputStream();
|
WasmOutputStream functionsStream = function.functionsStream = new WasmOutputStream( options );
|
||||||
functionsStream.writeVaruint32( localsStream.size() + localsTypeStream.size() + codeStream.size() + 1 );
|
functionsStream.writeVaruint32( localsStream.size() + localsTypeStream.size() + codeStream.size() + 1 );
|
||||||
localsStream.writeTo( functionsStream );
|
localsStream.writeTo( functionsStream );
|
||||||
localsTypeStream.writeTo( functionsStream );
|
localsTypeStream.writeTo( functionsStream );
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 - 2019 Volker Berlin (i-net software)
|
* Copyright 2017 - 2020 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -24,6 +24,7 @@ import javax.annotation.Nonnegative;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import de.inetsoftware.jwebassembly.WasmException;
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
|
import de.inetsoftware.jwebassembly.module.WasmOptions;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.LittleEndianOutputStream;
|
import de.inetsoftware.jwebassembly.wasm.LittleEndianOutputStream;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||||
@ -33,11 +34,17 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
|
|||||||
*/
|
*/
|
||||||
class WasmOutputStream extends LittleEndianOutputStream {
|
class WasmOutputStream extends LittleEndianOutputStream {
|
||||||
|
|
||||||
|
private final WasmOptions options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a in memory stream.
|
* Create a in memory stream.
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
* compiler properties
|
||||||
*/
|
*/
|
||||||
WasmOutputStream() {
|
WasmOutputStream( WasmOptions options ) {
|
||||||
super();
|
super();
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,9 +52,12 @@ class WasmOutputStream extends LittleEndianOutputStream {
|
|||||||
*
|
*
|
||||||
* @param output
|
* @param output
|
||||||
* the target of data
|
* the target of data
|
||||||
|
* @param options
|
||||||
|
* compiler properties
|
||||||
*/
|
*/
|
||||||
WasmOutputStream( OutputStream output ) {
|
WasmOutputStream( WasmOptions options, OutputStream output ) {
|
||||||
super( output );
|
super( output );
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,8 +96,12 @@ class WasmOutputStream extends LittleEndianOutputStream {
|
|||||||
* if an I/O error occurs.
|
* if an I/O error occurs.
|
||||||
*/
|
*/
|
||||||
public void writeRefValueType( AnyType type ) throws IOException {
|
public void writeRefValueType( AnyType type ) throws IOException {
|
||||||
if( type.getCode() >= 0 ) {
|
if( type.isRefType() ) {
|
||||||
|
if( options.useGC() ) {
|
||||||
writeValueType( ValueType.ref_type );
|
writeValueType( ValueType.ref_type );
|
||||||
|
} else {
|
||||||
|
type = ValueType.anyref;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writeValueType( type );
|
writeValueType( type );
|
||||||
}
|
}
|
||||||
@ -192,7 +206,7 @@ class WasmOutputStream extends LittleEndianOutputStream {
|
|||||||
* if an I/O error occurs.
|
* if an I/O error occurs.
|
||||||
*/
|
*/
|
||||||
void writeDouble( double value ) throws IOException {
|
void writeDouble( double value ) throws IOException {
|
||||||
long l = Double.doubleToLongBits(value);
|
long l = Double.doubleToLongBits( value );
|
||||||
writeInt32( (int)l );
|
writeInt32( (int)l );
|
||||||
writeInt32( (int)(l >>> 32) );
|
writeInt32( (int)(l >>> 32) );
|
||||||
}
|
}
|
||||||
|
@ -860,17 +860,21 @@ class BranchManger {
|
|||||||
* Should be converted to the follow Wasm code for try/catch:
|
* Should be converted to the follow Wasm code for try/catch:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* block
|
|
||||||
* block (result anyref)
|
|
||||||
* try
|
* try
|
||||||
* code1
|
* code1
|
||||||
* catch
|
* catch
|
||||||
* br_on_exn 1 0
|
* block (param exnref)(result anyref)
|
||||||
|
* br_on_exn 0 0
|
||||||
* rethrow
|
* rethrow
|
||||||
* end
|
* end
|
||||||
* br 1
|
* local.tee $ex
|
||||||
|
* i32.const classIndex(Exception)
|
||||||
|
* call $.instanceof
|
||||||
|
* i32.eqz
|
||||||
|
* if
|
||||||
|
* local.get $ex
|
||||||
|
* throw 0
|
||||||
* end
|
* end
|
||||||
* local.set x
|
|
||||||
* code2
|
* code2
|
||||||
* end
|
* end
|
||||||
* code3
|
* code3
|
||||||
@ -910,25 +914,24 @@ class BranchManger {
|
|||||||
}
|
}
|
||||||
int startPos = tryBlock.startPosition;
|
int startPos = tryBlock.startPosition;
|
||||||
int catchPos = tryCatch.getHandler();
|
int catchPos = tryCatch.getHandler();
|
||||||
BranchNode outerBlock = new BranchNode( startPos, endPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END );
|
|
||||||
parent.add( outerBlock );
|
|
||||||
|
|
||||||
BranchNode innerBlock = new BranchNode( startPos, catchPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END, ValueType.anyref );
|
|
||||||
outerBlock.add( innerBlock );
|
|
||||||
|
|
||||||
BranchNode tryNode = new BranchNode( startPos, catchPos, WasmBlockOperator.TRY, null );
|
BranchNode tryNode = new BranchNode( startPos, catchPos, WasmBlockOperator.TRY, null );
|
||||||
innerBlock.add( tryNode );
|
parent.add( tryNode );
|
||||||
calculate( tryNode, parsedOperations.subList( 0, idx ) );
|
calculate( tryNode, parsedOperations.subList( 0, idx ) );
|
||||||
|
|
||||||
BranchNode catchNode = new BranchNode( catchPos, catchPos, WasmBlockOperator.CATCH, WasmBlockOperator.END );
|
BranchNode catchNode = new BranchNode( catchPos, endPos, WasmBlockOperator.CATCH, WasmBlockOperator.END );
|
||||||
innerBlock.add( catchNode );
|
parent.add( catchNode );
|
||||||
|
|
||||||
if( tryCatch.isFinally() ) {
|
if( tryCatch.isFinally() ) {
|
||||||
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.DROP, null ) );
|
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.DROP, null ) );
|
||||||
} else {
|
} else {
|
||||||
|
// unboxing the exnref on the stack to a reference of the exception
|
||||||
|
BranchNode unBoxing = new BranchNode( catchPos, catchPos, WasmBlockOperator.BLOCK, WasmBlockOperator.END, options.getCatchType() );
|
||||||
|
catchNode.add( unBoxing );
|
||||||
|
|
||||||
//TODO localVariables.getTempVariable( ValueType.exnref, catchPos, endPos ); https://github.com/WebAssembly/wabt/issues/1388
|
//TODO localVariables.getTempVariable( ValueType.exnref, catchPos, endPos ); https://github.com/WebAssembly/wabt/issues/1388
|
||||||
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR_ON_EXN, null, 1 ) );
|
unBoxing.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR_ON_EXN, null, 0 ) );
|
||||||
catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.RETHROW, null ) );
|
unBoxing.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.RETHROW, null ) );
|
||||||
|
|
||||||
// add a "if $exception instanceof type" check to the WASM code
|
// add a "if $exception instanceof type" check to the WASM code
|
||||||
StructType type = options.types.valueOf( tryCatch.getType().getName() );
|
StructType type = options.types.valueOf( tryCatch.getType().getName() );
|
||||||
@ -946,8 +949,6 @@ class BranchManger {
|
|||||||
instructions.add( ++instrPos, new WasmBlockInstruction( WasmBlockOperator.THROW, null, catchPos, lineNumber ) );
|
instructions.add( ++instrPos, new WasmBlockInstruction( WasmBlockOperator.THROW, null, catchPos, lineNumber ) );
|
||||||
instructions.add( ++instrPos, new WasmBlockInstruction( WasmBlockOperator.END, null, catchPos, lineNumber ) );
|
instructions.add( ++instrPos, new WasmBlockInstruction( WasmBlockOperator.END, null, catchPos, lineNumber ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
innerBlock.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR, null, 1 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -506,6 +506,14 @@ public class TypeManager {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isRefType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -21,11 +21,7 @@ import javax.annotation.Nonnull;
|
|||||||
|
|
||||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||||
import de.inetsoftware.jwebassembly.javascript.JavaScriptSyntheticFunctionName;
|
import de.inetsoftware.jwebassembly.javascript.JavaScriptSyntheticFunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.CodeOptimizer;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionManager;
|
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
|
||||||
import de.inetsoftware.jwebassembly.module.StringManager;
|
|
||||||
import de.inetsoftware.jwebassembly.module.TypeManager;
|
|
||||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,6 +61,30 @@ public class WasmOptions {
|
|||||||
|
|
||||||
private FunctionName cast;
|
private FunctionName cast;
|
||||||
|
|
||||||
|
private int catchTypeCode;
|
||||||
|
|
||||||
|
private AnyType catchType = new AnyType() {
|
||||||
|
@Override
|
||||||
|
public int getCode() {
|
||||||
|
return catchTypeCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRefType() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSubTypeOf( AnyType type ) {
|
||||||
|
return type == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(param exnref)(result anyref)";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of options
|
* Create a new instance of options
|
||||||
*
|
*
|
||||||
@ -184,4 +204,23 @@ public class WasmOptions {
|
|||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type for a catch block to unboxing the exnref into a anyref
|
||||||
|
*
|
||||||
|
* @return the type
|
||||||
|
*/
|
||||||
|
public AnyType getCatchType() {
|
||||||
|
return catchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dynamic type id for the catch type
|
||||||
|
*
|
||||||
|
* @param catchTypeCode
|
||||||
|
* the positive id
|
||||||
|
*/
|
||||||
|
public void setCatchType( int catchTypeCode ) {
|
||||||
|
this.catchTypeCode = catchTypeCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,9 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
newline( output );
|
newline( output );
|
||||||
output.append( "(event (param anyref))" );
|
output.append( "(event (param anyref))" );
|
||||||
inset = oldInset;
|
inset = oldInset;
|
||||||
|
|
||||||
|
options.setCatchType( types.size() );
|
||||||
|
types.add( options.getCatchType().toString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +313,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
private void writeTypeName( Appendable output, AnyType type ) throws IOException {
|
private void writeTypeName( Appendable output, AnyType type ) throws IOException {
|
||||||
if( type instanceof ValueType ) {
|
if( !type.isRefType() ) {
|
||||||
output.append( type.toString() );
|
output.append( type.toString() );
|
||||||
} else if( options.useGC() ) {
|
} else if( options.useGC() ) {
|
||||||
output.append( "(optref " ).append( normalizeName( type.toString() ) ).append( ')' );
|
output.append( "(optref " ).append( normalizeName( type.toString() ) ).append( ')' );
|
||||||
@ -714,14 +717,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
name = "return";
|
name = "return";
|
||||||
break;
|
break;
|
||||||
case IF:
|
case IF:
|
||||||
if( data == ValueType.empty ) {
|
name = blockWithResult( "if", (AnyType)data );
|
||||||
name = "if";
|
|
||||||
} else {
|
|
||||||
StringBuilder builder = new StringBuilder("if (result ");
|
|
||||||
writeTypeName( builder, (AnyType)data );
|
|
||||||
builder.append( ")" );
|
|
||||||
name = builder;
|
|
||||||
}
|
|
||||||
insetAfter++;
|
insetAfter++;
|
||||||
break;
|
break;
|
||||||
case ELSE:
|
case ELSE:
|
||||||
@ -737,14 +733,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
name = "drop";
|
name = "drop";
|
||||||
break;
|
break;
|
||||||
case BLOCK:
|
case BLOCK:
|
||||||
if( data == null ) {
|
name = blockWithResult( "block", (AnyType)data );
|
||||||
name = "block";
|
|
||||||
} else {
|
|
||||||
StringBuilder builder = new StringBuilder("block (result ");
|
|
||||||
writeTypeName( builder, (AnyType)data );
|
|
||||||
builder.append( ")" );
|
|
||||||
name = builder;
|
|
||||||
}
|
|
||||||
insetAfter++;
|
insetAfter++;
|
||||||
break;
|
break;
|
||||||
case BR:
|
case BR:
|
||||||
@ -797,6 +786,34 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
inset += insetAfter;
|
inset += insetAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a the result type for a block instruction
|
||||||
|
*
|
||||||
|
* @param blockName
|
||||||
|
* the name of the block for example "if" or "block"
|
||||||
|
* @param result
|
||||||
|
* the result type of the block
|
||||||
|
* @return the block with result type
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
private CharSequence blockWithResult( String blockName, AnyType result ) throws IOException {
|
||||||
|
if( result == null || result == ValueType.empty ) {
|
||||||
|
return blockName;
|
||||||
|
} else {
|
||||||
|
StringBuilder builder = new StringBuilder( blockName );
|
||||||
|
if( result.toString().contains( "(" ) ) {
|
||||||
|
builder.append( result );
|
||||||
|
} else {
|
||||||
|
builder.append( "(result " );
|
||||||
|
writeTypeName( builder, result );
|
||||||
|
builder.append( ")" );
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 - 2019 Volker Berlin (i-net software)
|
* Copyright 2018 - 2020 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -39,6 +39,13 @@ public interface AnyType {
|
|||||||
*/
|
*/
|
||||||
public int getCode();
|
public int getCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the type is a reference type. A GC reference to the heap.
|
||||||
|
*
|
||||||
|
* @return true, is GC type
|
||||||
|
*/
|
||||||
|
public boolean isRefType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if this is a sub type of given type.
|
* Check if this is a sub type of given type.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2019 Volker Berlin (i-net software)
|
* Copyright 2019 - 2020 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -50,6 +50,14 @@ public class ArrayType implements AnyType {
|
|||||||
return ValueType.anyref.getCode();
|
return ValueType.anyref.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isRefType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 - 2019 Volker Berlin (i-net software)
|
* Copyright 2017 - 2020 Volker Berlin (i-net software)
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -58,6 +58,14 @@ public enum ValueType implements AnyType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isRefType() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -336,7 +336,7 @@ public class WatParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ifElseEndI32() throws IOException {
|
public void ifElseEndI32() throws IOException {
|
||||||
test( "if (result i32) else end" );
|
test( "if(result i32) else end" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user