mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Refactor the writing of sections more object oriented.
This commit is contained in:
parent
c0c24cb2cc
commit
df7cb74bcc
@ -19,6 +19,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -88,10 +89,10 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
wasm.write( WASM_BINARY_MAGIC );
|
wasm.write( WASM_BINARY_MAGIC );
|
||||||
wasm.writeInt32( WASM_BINARY_VERSION );
|
wasm.writeInt32( WASM_BINARY_VERSION );
|
||||||
|
|
||||||
writeTypeSection();
|
writeSection( SectionType.Type, functionTypes );
|
||||||
writeImportSection();
|
writeSection( SectionType.Import, imports.values() );
|
||||||
writeFunctionSection();
|
writeSection( SectionType.Function, functions.values() );
|
||||||
writeGlobalSection();
|
writeSection( SectionType.Global, globals.values() );
|
||||||
writeExportSection();
|
writeExportSection();
|
||||||
writeCodeSection();
|
writeCodeSection();
|
||||||
|
|
||||||
@ -99,94 +100,24 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the type section to the output. This section contains the signatures of the functions.
|
* Write a section with list format to the output.
|
||||||
*
|
*
|
||||||
|
* @param type
|
||||||
|
* the type of the section
|
||||||
|
* @param entries
|
||||||
|
* the entries of the section
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
private void writeTypeSection() throws IOException {
|
private void writeSection( SectionType type, Collection<? extends SectionEntry> entries ) throws IOException {
|
||||||
int count = functionTypes.size();
|
int count = entries.size();
|
||||||
if( count > 0 ) {
|
if( count > 0 ) {
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream();
|
||||||
stream.writeVaruint32( count );
|
stream.writeVaruint32( count );
|
||||||
for( FunctionType type : functionTypes ) {
|
for( SectionEntry entry : entries ) {
|
||||||
stream.write( ValueType.func.getCode() );
|
entry.writeSectionEntry( stream );
|
||||||
stream.writeVaruint32( type.params.size() );
|
|
||||||
for( ValueType valueType : type.params ) {
|
|
||||||
stream.write( valueType.getCode() );
|
|
||||||
}
|
|
||||||
if( type.result == null ) {
|
|
||||||
stream.writeVaruint32( 0 );
|
|
||||||
} else {
|
|
||||||
stream.writeVaruint32( 1 );
|
|
||||||
stream.write( type.result.getCode() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
wasm.writeSection( SectionType.Type, stream, null );
|
wasm.writeSection( type, stream, null );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the import section to the output. This section declare all imports.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
*/
|
|
||||||
private void writeImportSection() throws IOException {
|
|
||||||
int count = imports.size();
|
|
||||||
if( count > 0 ) {
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
|
||||||
stream.writeVaruint32( count );
|
|
||||||
for( ImportFunction importFunction : imports.values() ) {
|
|
||||||
byte[] bytes = importFunction.module.getBytes( StandardCharsets.UTF_8 );
|
|
||||||
stream.writeVaruint32( bytes.length );
|
|
||||||
stream.write( bytes );
|
|
||||||
bytes = importFunction.name.getBytes( StandardCharsets.UTF_8 );
|
|
||||||
stream.writeVaruint32( bytes.length );
|
|
||||||
stream.write( bytes );
|
|
||||||
stream.writeVaruint32( ExternalKind.Function.ordinal() );
|
|
||||||
stream.writeVaruint32( importFunction.typeId );
|
|
||||||
}
|
|
||||||
wasm.writeSection( SectionType.Import, stream, null );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the function section to the output. This section contains a mapping from the function index to the type signature index.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
*/
|
|
||||||
private void writeFunctionSection() throws IOException {
|
|
||||||
int count = functions.size();
|
|
||||||
if( count > 0 ) {
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
|
||||||
stream.writeVaruint32( count );
|
|
||||||
for( Function func : functions.values() ) {
|
|
||||||
stream.writeVaruint32( func.typeId );
|
|
||||||
}
|
|
||||||
wasm.writeSection( SectionType.Function, stream, null );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the global section to the output. This section contains a declaring of global (static) variables.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
*/
|
|
||||||
private void writeGlobalSection() throws IOException {
|
|
||||||
int count = globals.size();
|
|
||||||
if( count > 0 ) {
|
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
|
||||||
stream.writeVaruint32( count );
|
|
||||||
for( Global var : globals.values() ) {
|
|
||||||
stream.write( var.type.getCode() );
|
|
||||||
stream.write( var.mutability ? 1 : 0 );
|
|
||||||
writeConst( stream, 0, var.type );
|
|
||||||
stream.writeOpCode( END );
|
|
||||||
}
|
|
||||||
wasm.writeSection( SectionType.Global, stream, null );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,42 +266,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void writeConst( Number value, ValueType valueType ) throws IOException {
|
protected void writeConst( Number value, ValueType valueType ) throws IOException {
|
||||||
writeConst( codeStream, value, valueType );
|
codeStream.writeConst( value, valueType );
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a constant number value
|
|
||||||
*
|
|
||||||
* @param codeStream
|
|
||||||
* the target stream
|
|
||||||
* @param value
|
|
||||||
* the value
|
|
||||||
* @param valueType
|
|
||||||
* the data type of the number
|
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
*/
|
|
||||||
private static void writeConst( WasmOutputStream codeStream, Number value, ValueType valueType ) throws IOException {
|
|
||||||
switch( valueType ) {
|
|
||||||
case i32:
|
|
||||||
codeStream.writeOpCode( I32_CONST );
|
|
||||||
codeStream.writeVarint( value.intValue() );
|
|
||||||
break;
|
|
||||||
case i64:
|
|
||||||
codeStream.writeOpCode( I64_CONST );
|
|
||||||
codeStream.writeVarint( value.longValue() );
|
|
||||||
break;
|
|
||||||
case f32:
|
|
||||||
codeStream.writeOpCode( F32_CONST );
|
|
||||||
codeStream.writeFloat( value.floatValue() );
|
|
||||||
break;
|
|
||||||
case f64:
|
|
||||||
codeStream.writeOpCode( F64_CONST );
|
|
||||||
codeStream.writeDouble( value.doubleValue() );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error( valueType + " " + value );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,15 +15,24 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.binary;
|
package de.inetsoftware.jwebassembly.binary;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entry in the function section of the WebAssembly.
|
* An entry in the function section of the WebAssembly.
|
||||||
*
|
*
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*/
|
*/
|
||||||
class Function {
|
class Function extends SectionEntry {
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
int typeId;
|
int typeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void writeSectionEntry( WasmOutputStream stream ) throws IOException {
|
||||||
|
stream.writeVaruint32( this.typeId );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.binary;
|
package de.inetsoftware.jwebassembly.binary;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -26,12 +27,30 @@ import de.inetsoftware.jwebassembly.module.ValueType;
|
|||||||
*
|
*
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*/
|
*/
|
||||||
class FunctionType {
|
class FunctionType extends SectionEntry {
|
||||||
|
|
||||||
final List<ValueType> params = new ArrayList<>();
|
final List<ValueType> params = new ArrayList<>();
|
||||||
|
|
||||||
ValueType result; // Java has only one return parameter
|
ValueType result; // Java has only one return parameter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void writeSectionEntry( WasmOutputStream stream ) throws IOException {
|
||||||
|
stream.write( ValueType.func.getCode() );
|
||||||
|
stream.writeVaruint32( this.params.size() );
|
||||||
|
for( ValueType valueType : this.params ) {
|
||||||
|
stream.write( valueType.getCode() );
|
||||||
|
}
|
||||||
|
if( this.result == null ) {
|
||||||
|
stream.writeVaruint32( 0 );
|
||||||
|
} else {
|
||||||
|
stream.writeVaruint32( 1 );
|
||||||
|
stream.write( this.result.getCode() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.binary;
|
package de.inetsoftware.jwebassembly.binary;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import de.inetsoftware.jwebassembly.module.ValueType;
|
import de.inetsoftware.jwebassembly.module.ValueType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,11 +24,22 @@ import de.inetsoftware.jwebassembly.module.ValueType;
|
|||||||
*
|
*
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*/
|
*/
|
||||||
class Global {
|
class Global extends SectionEntry {
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
ValueType type;
|
ValueType type;
|
||||||
|
|
||||||
boolean mutability;
|
boolean mutability;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void writeSectionEntry( WasmOutputStream stream ) throws IOException {
|
||||||
|
stream.write( this.type.getCode() );
|
||||||
|
stream.write( this.mutability ? 1 : 0 );
|
||||||
|
stream.writeConst( 0, this.type );
|
||||||
|
stream.writeOpCode( InstructionOpcodes.END );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.binary;
|
package de.inetsoftware.jwebassembly.binary;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entry in the import section of the WebAssembly.
|
* An entry in the import section of the WebAssembly.
|
||||||
*
|
*
|
||||||
@ -30,4 +33,19 @@ class ImportFunction extends Function {
|
|||||||
this.module = module;
|
this.module = module;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void writeSectionEntry( WasmOutputStream stream ) throws IOException {
|
||||||
|
byte[] bytes = this.module.getBytes( StandardCharsets.UTF_8 );
|
||||||
|
stream.writeVaruint32( bytes.length );
|
||||||
|
stream.write( bytes );
|
||||||
|
bytes = this.name.getBytes( StandardCharsets.UTF_8 );
|
||||||
|
stream.writeVaruint32( bytes.length );
|
||||||
|
stream.write( bytes );
|
||||||
|
stream.writeVaruint32( ExternalKind.Function.ordinal() );
|
||||||
|
stream.writeVaruint32( this.typeId );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ import java.nio.charset.StandardCharsets;
|
|||||||
|
|
||||||
import javax.annotation.Nonnegative;
|
import javax.annotation.Nonnegative;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.module.ValueType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*/
|
*/
|
||||||
@ -147,6 +149,39 @@ class WasmOutputStream extends FilterOutputStream {
|
|||||||
writeInt32( (int)(l >>> 32) );
|
writeInt32( (int)(l >>> 32) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a constant number value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the value
|
||||||
|
* @param valueType
|
||||||
|
* the data type of the number
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
void writeConst( Number value, ValueType valueType ) throws IOException {
|
||||||
|
switch( valueType ) {
|
||||||
|
case i32:
|
||||||
|
this.writeOpCode( InstructionOpcodes.I32_CONST );
|
||||||
|
this.writeVarint( value.intValue() );
|
||||||
|
break;
|
||||||
|
case i64:
|
||||||
|
this.writeOpCode( InstructionOpcodes.I64_CONST );
|
||||||
|
this.writeVarint( value.longValue() );
|
||||||
|
break;
|
||||||
|
case f32:
|
||||||
|
this.writeOpCode( InstructionOpcodes.F32_CONST );
|
||||||
|
this.writeFloat( value.floatValue() );
|
||||||
|
break;
|
||||||
|
case f64:
|
||||||
|
this.writeOpCode( InstructionOpcodes.F64_CONST );
|
||||||
|
this.writeDouble( value.doubleValue() );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error( valueType + " " + value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a section with header and data.
|
* Write a section with header and data.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user