mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
Add support for i32.load to the wat parser and some small bug fixes
This commit is contained in:
parent
86d239986e
commit
947f66502b
@ -33,6 +33,7 @@ import de.inetsoftware.jwebassembly.javascript.NonGC;
|
||||
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
|
||||
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;
|
||||
@ -356,7 +357,20 @@ public abstract class WasmCodeBuilder {
|
||||
if( id == null ) {
|
||||
strings.put( (String)value, id = strings.size() );
|
||||
}
|
||||
FunctionName name = getNonGC( "stringConstant", lineNumber );
|
||||
String wat = "local.get 0 " + //
|
||||
"table.get 1 " + // strings table
|
||||
"local.tee 1 " + //
|
||||
"ref.is_null " + //
|
||||
"if " + //
|
||||
"local.get 0 " + //
|
||||
"i32.const 4 " + //
|
||||
"i32.mul " + //
|
||||
"i32.load offset=0 " + //
|
||||
"drop " + //
|
||||
"end " + //
|
||||
"local.get 1 " + //
|
||||
"return";
|
||||
FunctionName name = new WatCodeSyntheticFunctionName( "stringConstant", wat, ValueType.i32, null, ValueType.anyref );
|
||||
instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) );
|
||||
addCallInstruction( name, javaCodePos, lineNumber );
|
||||
} else {
|
||||
@ -586,4 +600,24 @@ public abstract class WasmCodeBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a load/store to the linear memory 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
|
||||
*/
|
||||
protected void addMemoryInstruction( MemoryOperator op, ValueType type, int offset, int alignment, int javaCodePos, int lineNumber ) {
|
||||
instructions.add( new WasmMemoryInstruction( op, type, offset, alignment, javaCodePos, lineNumber ) );
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,10 @@ class WasmMemoryInstruction extends WasmInstruction {
|
||||
|
||||
private int offset;
|
||||
|
||||
private int aligment;
|
||||
private int alignment;
|
||||
|
||||
/**
|
||||
* Create an instance of a load/store instruction
|
||||
* Create an instance of a load/store to the linear memory instruction
|
||||
*
|
||||
* @param op
|
||||
* the operation
|
||||
@ -56,12 +56,12 @@ class WasmMemoryInstruction extends WasmInstruction {
|
||||
* @param lineNumber
|
||||
* the line number in the Java source code
|
||||
*/
|
||||
WasmMemoryInstruction( MemoryOperator op, ValueType type, int offset, int aligment, int javaCodePos, int lineNumber ) {
|
||||
WasmMemoryInstruction( MemoryOperator op, ValueType type, int offset, int alignment, int javaCodePos, int lineNumber ) {
|
||||
super( javaCodePos, lineNumber );
|
||||
this.op = op;
|
||||
this.type = type;
|
||||
this.offset = offset;
|
||||
this.aligment = aligment;
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +77,7 @@ class WasmMemoryInstruction extends WasmInstruction {
|
||||
*/
|
||||
@Override
|
||||
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
||||
writer.writeMemoryOperator( op, type, offset, aligment );
|
||||
writer.writeMemoryOperator( op, type, offset, alignment );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,8 +149,10 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
if( stringCount > 0 ) {
|
||||
if( !callIndirect ) {
|
||||
// we need to create a placeholder table with index 0 if not exists
|
||||
newline( output );
|
||||
output.append( "(table 0 funcref)" );
|
||||
}
|
||||
newline( output );
|
||||
output.append( "(table " ).append( Integer.toString( stringCount ) ).append( " anyref)" );
|
||||
}
|
||||
|
||||
@ -843,6 +845,6 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
newline( methodOutput );
|
||||
methodOutput.append( valueType ).append( '.' ).append( memOp )
|
||||
.append( " offset=" ).append( offset )
|
||||
.append( " align=" ).append( alignment );
|
||||
.append( " align=" ).append( 1 << alignment );
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import de.inetsoftware.classparser.MethodInfo;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.module.WasmCodeBuilder;
|
||||
import de.inetsoftware.jwebassembly.wasm.MemoryOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||
@ -220,6 +221,12 @@ public class WatParser extends WasmCodeBuilder {
|
||||
case "end":
|
||||
addBlockInstruction( WasmBlockOperator.END, null, javaCodePos, lineNumber );
|
||||
break;
|
||||
case "drop":
|
||||
addBlockInstruction( WasmBlockOperator.DROP, null, javaCodePos, lineNumber );
|
||||
break;
|
||||
case "i32.load":
|
||||
i = addMemoryInstruction( MemoryOperator.load, ValueType.i32, tokens, i, lineNumber );
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Unknown WASM token: " + tok, lineNumber );
|
||||
}
|
||||
@ -301,4 +308,51 @@ public class WatParser extends WasmCodeBuilder {
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the optional tokens of a load memory instruction and add it.
|
||||
*
|
||||
* @param op
|
||||
* the operation
|
||||
* @param type
|
||||
* the type of the static field
|
||||
* @param tokens
|
||||
* the token list
|
||||
* @param i
|
||||
* the position in the tokens
|
||||
* @param lineNumber
|
||||
* the line number in the Java source code
|
||||
* @return the current index to the tokens
|
||||
*/
|
||||
private int addMemoryInstruction( MemoryOperator op, ValueType type, List<String> tokens, int i, int lineNumber ) {
|
||||
int offset = 0;
|
||||
int alignment = 0;
|
||||
if( i < tokens.size() ) {
|
||||
String str = tokens.get( i + 1 );
|
||||
if( str.startsWith( "offset=" ) ) {
|
||||
offset = Integer.parseInt( str.substring( 7 ) );
|
||||
i++;
|
||||
}
|
||||
str = tokens.get( i + 1 );
|
||||
if( str.startsWith( "align=" ) ) {
|
||||
int align = Integer.parseInt( str.substring( 6 ) );
|
||||
switch( align ) {
|
||||
case 1:
|
||||
alignment = 0;
|
||||
break;
|
||||
case 2:
|
||||
alignment = 1;
|
||||
break;
|
||||
case 4:
|
||||
alignment = 2;
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "alignment must be power-of-two", lineNumber );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
addMemoryInstruction( op, type, offset, alignment, i, lineNumber );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -315,6 +315,11 @@ public class WatParserTest {
|
||||
test( "if (result i32) else end" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void drop() throws IOException {
|
||||
test( "drop" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void table_get() throws IOException {
|
||||
test( "table.get 1" );
|
||||
@ -326,6 +331,11 @@ public class WatParserTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void i32_load() throws IOException {
|
||||
test( "i32.load offset=2 align=1" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorMissingToken() throws IOException {
|
||||
testError( "i32.const", "Missing Token in wasm text format after token: i32.const" );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user