mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +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.module.WasmInstruction.Type;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||||
|
import de.inetsoftware.jwebassembly.wasm.MemoryOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
import de.inetsoftware.jwebassembly.wasm.StructOperator;
|
||||||
@ -356,7 +357,20 @@ public abstract class WasmCodeBuilder {
|
|||||||
if( id == null ) {
|
if( id == null ) {
|
||||||
strings.put( (String)value, id = strings.size() );
|
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 ) );
|
instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) );
|
||||||
addCallInstruction( name, javaCodePos, lineNumber );
|
addCallInstruction( name, javaCodePos, lineNumber );
|
||||||
} else {
|
} 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 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
|
* @param op
|
||||||
* the operation
|
* the operation
|
||||||
@ -56,12 +56,12 @@ class WasmMemoryInstruction extends WasmInstruction {
|
|||||||
* @param lineNumber
|
* @param lineNumber
|
||||||
* the line number in the Java source code
|
* 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 );
|
super( javaCodePos, lineNumber );
|
||||||
this.op = op;
|
this.op = op;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.aligment = aligment;
|
this.alignment = alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +77,7 @@ class WasmMemoryInstruction extends WasmInstruction {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
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( stringCount > 0 ) {
|
||||||
if( !callIndirect ) {
|
if( !callIndirect ) {
|
||||||
// we need to create a placeholder table with index 0 if not exists
|
// we need to create a placeholder table with index 0 if not exists
|
||||||
|
newline( output );
|
||||||
output.append( "(table 0 funcref)" );
|
output.append( "(table 0 funcref)" );
|
||||||
}
|
}
|
||||||
|
newline( output );
|
||||||
output.append( "(table " ).append( Integer.toString( stringCount ) ).append( " anyref)" );
|
output.append( "(table " ).append( Integer.toString( stringCount ) ).append( " anyref)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,6 +845,6 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
newline( methodOutput );
|
newline( methodOutput );
|
||||||
methodOutput.append( valueType ).append( '.' ).append( memOp )
|
methodOutput.append( valueType ).append( '.' ).append( memOp )
|
||||||
.append( " offset=" ).append( offset )
|
.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.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||||
import de.inetsoftware.jwebassembly.module.WasmCodeBuilder;
|
import de.inetsoftware.jwebassembly.module.WasmCodeBuilder;
|
||||||
|
import de.inetsoftware.jwebassembly.wasm.MemoryOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
import de.inetsoftware.jwebassembly.wasm.NumericOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
||||||
@ -220,6 +221,12 @@ public class WatParser extends WasmCodeBuilder {
|
|||||||
case "end":
|
case "end":
|
||||||
addBlockInstruction( WasmBlockOperator.END, null, javaCodePos, lineNumber );
|
addBlockInstruction( WasmBlockOperator.END, null, javaCodePos, lineNumber );
|
||||||
break;
|
break;
|
||||||
|
case "drop":
|
||||||
|
addBlockInstruction( WasmBlockOperator.DROP, null, javaCodePos, lineNumber );
|
||||||
|
break;
|
||||||
|
case "i32.load":
|
||||||
|
i = addMemoryInstruction( MemoryOperator.load, ValueType.i32, tokens, i, lineNumber );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new WasmException( "Unknown WASM token: " + tok, lineNumber );
|
throw new WasmException( "Unknown WASM token: " + tok, lineNumber );
|
||||||
}
|
}
|
||||||
@ -301,4 +308,51 @@ public class WatParser extends WasmCodeBuilder {
|
|||||||
}
|
}
|
||||||
return tokens;
|
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( "if (result i32) else end" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void drop() throws IOException {
|
||||||
|
test( "drop" );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void table_get() throws IOException {
|
public void table_get() throws IOException {
|
||||||
test( "table.get 1" );
|
test( "table.get 1" );
|
||||||
@ -326,6 +331,11 @@ public class WatParserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
public void i32_load() throws IOException {
|
||||||
|
test( "i32.load offset=2 align=1" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void errorMissingToken() throws IOException {
|
public void errorMissingToken() throws IOException {
|
||||||
testError( "i32.const", "Missing Token in wasm text format after token: i32.const" );
|
testError( "i32.const", "Missing Token in wasm text format after token: i32.const" );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user