diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index eff1c0c..5f539fa 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -37,6 +37,7 @@ import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter; import de.inetsoftware.jwebassembly.sourcemap.SourceMapping; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ArrayOperator; +import de.inetsoftware.jwebassembly.wasm.MemoryOperator; import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator; @@ -1319,9 +1320,25 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod * {@inheritDoc} */ @Override - protected void writeLoadI32( int offset ) throws IOException { + protected void writeMemoryOperator( MemoryOperator memOp, ValueType valueType, int offset, int alignment ) throws IOException { + int op = 0; + switch( memOp ) { + case load: + switch( valueType ) { + case i32: + op = I32_LOAD; + break; + case i64: + op = I64_LOAD; + break; + } + break; + } + if( op == 0 ) { + throw new Error( valueType + "." + memOp ); + } codeStream.writeOpCode( I32_LOAD ); - codeStream.write( 2 ); // 32 alignment + codeStream.write( alignment ); // 0: 8 Bit; 1: 16 Bit; 2: 32 Bit of the resulting offset codeStream.writeVaruint32( offset ); } } diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java index 14edf38..77d003d 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java @@ -26,6 +26,7 @@ import javax.annotation.Nullable; import de.inetsoftware.jwebassembly.module.TypeManager.StructType; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ArrayOperator; +import de.inetsoftware.jwebassembly.wasm.MemoryOperator; import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator; @@ -344,12 +345,18 @@ public abstract class ModuleWriter implements Closeable { protected abstract void writeStructOperator( StructOperator op, AnyType type, NamedStorageType fieldName, int idx ) throws IOException; /** - * Write a i32.load operation from linear memory + * Write a memory operation for the linear memory. * + * @param memOp + * the memory operation + * @param valueType + * the value type of the stack value * @param offset * the offset into the memory. Should be ideally a factor of 4. + * @param alignment + * the alignment of the value on the linear memory (0: 8 Bit; 1: 16 Bit; 2: 32 Bit) * @throws IOException * if any I/O error occur */ - protected abstract void writeLoadI32( int offset ) throws IOException; + protected abstract void writeMemoryOperator( MemoryOperator memOp, ValueType valueType, int offset, int alignment ) throws IOException; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java index 73e255a..66c8baa 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java @@ -22,6 +22,7 @@ import javax.annotation.Nonnull; import de.inetsoftware.jwebassembly.javascript.JavaScriptSyntheticFunctionName; import de.inetsoftware.jwebassembly.module.TypeManager.StructType; +import de.inetsoftware.jwebassembly.wasm.MemoryOperator; import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.StructOperator; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -124,7 +125,7 @@ class WasmCallIndirectInstruction extends WasmCallInstruction { writer.writeConst( 0, ValueType.i32 ); // vtable is ever on position 0 writer.writeFunctionCall( new JavaScriptSyntheticFunctionName( "NonGC", "get_i32", () -> "(a,i) => a[i]", ValueType.anyref, ValueType.i32, null, ValueType.i32 ) ); } - writer.writeLoadI32( virtualFunctionIdx * 4 ); + writer.writeMemoryOperator( MemoryOperator.load, ValueType.i32, virtualFunctionIdx * 4, 2 ); writer.writeVirtualFunctionCall( getFunctionName(), type ); } } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java index 81beede..a8cbdb3 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java @@ -35,7 +35,7 @@ abstract class WasmInstruction { * Type of instruction to faster differ as with instanceof. */ static enum Type { - Const, Convert, Local, Global, Table, Block, Numeric, Nop, Call, CallIndirect, Array, Struct, Dup, DupThis; + Const, Convert, Local, Global, Table, Memory, Block, Numeric, Nop, Call, CallIndirect, Array, Struct, Dup, DupThis; } private int javaCodePos; diff --git a/src/de/inetsoftware/jwebassembly/module/WasmMemoryInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmMemoryInstruction.java new file mode 100644 index 0000000..82a9026 --- /dev/null +++ b/src/de/inetsoftware/jwebassembly/module/WasmMemoryInstruction.java @@ -0,0 +1,98 @@ +/* + Copyright 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. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +package de.inetsoftware.jwebassembly.module; + +import java.io.IOException; + +import javax.annotation.Nonnull; + +import de.inetsoftware.jwebassembly.wasm.AnyType; +import de.inetsoftware.jwebassembly.wasm.MemoryOperator; +import de.inetsoftware.jwebassembly.wasm.ValueType; + +/** + * WasmInstruction for load and store to the linear memory. + * + * @author Volker Berlin + * + */ +class WasmMemoryInstruction extends WasmInstruction { + + private MemoryOperator op; + + private ValueType type; + + private int offset; + + private int aligment; + + /** + * Create an instance of a load/store instruction + * + * @param op + * the operation + * @param type + * the type of the static field + * @param offset + * the base offset which will be added to the offset value on the stack + * @param alignment + * the alignment of the value on the linear memory (0: 8 Bit; 1: 16 Bit; 2: 32 Bit) + * @param javaCodePos + * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code + */ + WasmMemoryInstruction( MemoryOperator op, ValueType type, int offset, int aligment, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); + this.op = op; + this.type = type; + this.offset = offset; + this.aligment = aligment; + } + + /** + * {@inheritDoc} + */ + @Override + Type getType() { + return Type.Memory; + } + + /** + * {@inheritDoc} + */ + @Override + public void writeTo( @Nonnull ModuleWriter writer ) throws IOException { + writer.writeMemoryOperator( op, type, offset, aligment ); + } + + /** + * {@inheritDoc} + */ + @Override + AnyType getPushValueType() { + return op.name().startsWith( "load" ) ? type : null; + } + + /** + * {@inheritDoc} + */ + @Override + int getPopCount() { + return op.name().startsWith( "load" ) ? 0 : 1; + } +} diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 21b87a8..5eb4ad0 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -15,7 +15,6 @@ */ package de.inetsoftware.jwebassembly.text; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -37,6 +36,7 @@ import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; import de.inetsoftware.jwebassembly.module.WasmTarget; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ArrayOperator; +import de.inetsoftware.jwebassembly.wasm.MemoryOperator; import de.inetsoftware.jwebassembly.wasm.NamedStorageType; import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.StructOperator; @@ -839,8 +839,10 @@ public class TextModuleWriter extends ModuleWriter { * {@inheritDoc} */ @Override - protected void writeLoadI32( int offset ) throws IOException { + protected void writeMemoryOperator( MemoryOperator memOp, ValueType valueType, int offset, int alignment ) throws IOException { newline( methodOutput ); - methodOutput.append( "i32.load offset=" ).append( offset ); // use default alignment + methodOutput.append( valueType ).append( '.' ).append( memOp ) + .append( " offset=" ).append( offset ) + .append( " align=" ).append( alignment ); } } diff --git a/src/de/inetsoftware/jwebassembly/wasm/MemoryOperator.java b/src/de/inetsoftware/jwebassembly/wasm/MemoryOperator.java new file mode 100644 index 0000000..814f644 --- /dev/null +++ b/src/de/inetsoftware/jwebassembly/wasm/MemoryOperator.java @@ -0,0 +1,28 @@ +/* + Copyright 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. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +package de.inetsoftware.jwebassembly.wasm; + +/** + * @author Volker Berlin + */ +public enum MemoryOperator { + load8_s, + load8_u, + load16_s, + load16_u, + load, +}