add memory instructions

This commit is contained in:
Volker Berlin 2019-11-18 20:08:18 +01:00
parent ed00c7a02f
commit 86d239986e
7 changed files with 162 additions and 9 deletions

View File

@ -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 );
}
}

View File

@ -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;
}

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 );
}
}

View File

@ -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,
}