mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
add support for mul and div
This commit is contained in:
parent
f5928ab1d4
commit
d2eb2e160f
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||||
import de.inetsoftware.jwebassembly.module.ValueType;
|
import de.inetsoftware.jwebassembly.module.ValueType;
|
||||||
@ -322,6 +323,48 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case mul:
|
||||||
|
switch( valueType ) {
|
||||||
|
case i32:
|
||||||
|
op = I32_MUL;
|
||||||
|
break;
|
||||||
|
case i64:
|
||||||
|
op = I64_MUL;
|
||||||
|
break;
|
||||||
|
case f32:
|
||||||
|
op = F32_MUL;
|
||||||
|
break;
|
||||||
|
case f64:
|
||||||
|
op = F64_MUL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case div:
|
||||||
|
switch( valueType ) {
|
||||||
|
case i32:
|
||||||
|
op = I32_DIV_S;
|
||||||
|
break;
|
||||||
|
case i64:
|
||||||
|
op = I64_DIV_S;
|
||||||
|
break;
|
||||||
|
case f32:
|
||||||
|
op = F32_DIV;
|
||||||
|
break;
|
||||||
|
case f64:
|
||||||
|
op = F64_DIV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case rem:
|
||||||
|
switch( valueType ) {
|
||||||
|
case i32:
|
||||||
|
op = I32_REM_S;
|
||||||
|
break;
|
||||||
|
case i64:
|
||||||
|
op = I64_REM_S;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if( op == 0 ) {
|
if( op == 0 ) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
|
@ -57,18 +57,38 @@ interface InstructionOpcodes {
|
|||||||
|
|
||||||
static final int I32_SUB = 0x6B;
|
static final int I32_SUB = 0x6B;
|
||||||
|
|
||||||
|
static final int I32_MUL = 0x6C;
|
||||||
|
|
||||||
|
static final int I32_DIV_S = 0x6D;
|
||||||
|
|
||||||
|
static final int I32_REM_S = 0x6F;
|
||||||
|
|
||||||
static final int I64_ADD = 0x7C;
|
static final int I64_ADD = 0x7C;
|
||||||
|
|
||||||
static final int I64_SUB = 0x7D;
|
static final int I64_SUB = 0x7D;
|
||||||
|
|
||||||
|
static final int I64_MUL = 0x7E;
|
||||||
|
|
||||||
|
static final int I64_DIV_S = 0x7F;
|
||||||
|
|
||||||
|
static final int I64_REM_S = 0x81;
|
||||||
|
|
||||||
static final int F32_ADD = 0x92;
|
static final int F32_ADD = 0x92;
|
||||||
|
|
||||||
static final int F32_SUB = 0x93;
|
static final int F32_SUB = 0x93;
|
||||||
|
|
||||||
|
static final int F32_MUL = 0x94;
|
||||||
|
|
||||||
|
static final int F32_DIV = 0x95;
|
||||||
|
|
||||||
static final int F64_ADD = 0xA0;
|
static final int F64_ADD = 0xA0;
|
||||||
|
|
||||||
static final int F64_SUB = 0xA1;
|
static final int F64_SUB = 0xA1;
|
||||||
|
|
||||||
|
static final int F64_MUL = 0xA2;
|
||||||
|
|
||||||
|
static final int F64_DIV = 0xA3;
|
||||||
|
|
||||||
// === data type conversions =====
|
// === data type conversions =====
|
||||||
|
|
||||||
static final int I32_WRAP_I64 = 0xA7;
|
static final int I32_WRAP_I64 = 0xA7;
|
||||||
|
@ -269,9 +269,21 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
case 10: // lconst_1
|
case 10: // lconst_1
|
||||||
writeConstLong( op - 9 );
|
writeConstLong( op - 9 );
|
||||||
break;
|
break;
|
||||||
|
case 11: // fconst_0
|
||||||
|
case 12: // fconst_1
|
||||||
|
case 13: // fconst_2
|
||||||
|
writeConstFloat( op - 11 );
|
||||||
|
break;
|
||||||
|
case 14: // dconst_0
|
||||||
|
case 15: // dconst_1
|
||||||
|
writeConstDouble( op - 14 );
|
||||||
|
break;
|
||||||
case 16: // bipush
|
case 16: // bipush
|
||||||
writeConstInt( byteCode.readByte() );
|
writeConstInt( byteCode.readByte() );
|
||||||
break;
|
break;
|
||||||
|
case 17: // sipush
|
||||||
|
writeConstInt( byteCode.readShort() );
|
||||||
|
break;
|
||||||
case 18: // ldc
|
case 18: // ldc
|
||||||
writeConst( constantPool.get( byteCode.readUnsignedByte() ) );
|
writeConst( constantPool.get( byteCode.readUnsignedByte() ) );
|
||||||
break;
|
break;
|
||||||
@ -314,6 +326,18 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
case 66: // lstore_3
|
case 66: // lstore_3
|
||||||
writeLoadStore( false, ValueType.i64, op - 63 );
|
writeLoadStore( false, ValueType.i64, op - 63 );
|
||||||
break;
|
break;
|
||||||
|
case 67: // fstore_0
|
||||||
|
case 68: // fstore_1
|
||||||
|
case 69: // fstore_2
|
||||||
|
case 70: // fstore_3
|
||||||
|
writeLoadStore( false, ValueType.f32, op - 67 );
|
||||||
|
break;
|
||||||
|
case 71: // dstore_0
|
||||||
|
case 72: // dstore_1
|
||||||
|
case 73: // dstore_2
|
||||||
|
case 74: // dstore_3
|
||||||
|
writeLoadStore( false, ValueType.f64, op - 71 );
|
||||||
|
break;
|
||||||
case 96: // iadd
|
case 96: // iadd
|
||||||
writeNumericOperator( NumericOperator.add, ValueType.i32);
|
writeNumericOperator( NumericOperator.add, ValueType.i32);
|
||||||
break;
|
break;
|
||||||
@ -338,6 +362,39 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
case 103: // dsub
|
case 103: // dsub
|
||||||
writeNumericOperator( NumericOperator.sub, ValueType.f64 );
|
writeNumericOperator( NumericOperator.sub, ValueType.f64 );
|
||||||
break;
|
break;
|
||||||
|
case 104: // imul;
|
||||||
|
writeNumericOperator( NumericOperator.mul, ValueType.i32 );
|
||||||
|
break;
|
||||||
|
case 105: // lmul
|
||||||
|
writeNumericOperator( NumericOperator.mul, ValueType.i64 );
|
||||||
|
break;
|
||||||
|
case 106: // fmul
|
||||||
|
writeNumericOperator( NumericOperator.mul, ValueType.f32 );
|
||||||
|
break;
|
||||||
|
case 107: // dmul
|
||||||
|
writeNumericOperator( NumericOperator.mul, ValueType.f64 );
|
||||||
|
break;
|
||||||
|
case 108: // idiv
|
||||||
|
writeNumericOperator( NumericOperator.div, ValueType.i32 );
|
||||||
|
break;
|
||||||
|
case 109: // ldiv
|
||||||
|
writeNumericOperator( NumericOperator.div, ValueType.i64 );
|
||||||
|
break;
|
||||||
|
case 110: // fdiv
|
||||||
|
writeNumericOperator( NumericOperator.div, ValueType.f32 );
|
||||||
|
break;
|
||||||
|
case 111: // ddiv
|
||||||
|
writeNumericOperator( NumericOperator.div, ValueType.f64 );
|
||||||
|
break;
|
||||||
|
case 112: // irem
|
||||||
|
writeNumericOperator( NumericOperator.rem, ValueType.i32 );
|
||||||
|
break;
|
||||||
|
case 113: // lrem
|
||||||
|
writeNumericOperator( NumericOperator.rem, ValueType.i64 );
|
||||||
|
break;
|
||||||
|
case 114: // frem
|
||||||
|
case 115: // drem
|
||||||
|
throw new WasmException( "Modulo/Remainder for floating numbers is not supported in WASM. Use int or long data types." + op, sourceFile, lineNumber );
|
||||||
case 136: // l2i
|
case 136: // l2i
|
||||||
writeCast( ValueTypeConvertion.l2i );
|
writeCast( ValueTypeConvertion.l2i );
|
||||||
break;
|
break;
|
||||||
|
@ -21,4 +21,7 @@ package de.inetsoftware.jwebassembly.module;
|
|||||||
public enum NumericOperator {
|
public enum NumericOperator {
|
||||||
add,
|
add,
|
||||||
sub,
|
sub,
|
||||||
|
mul,
|
||||||
|
div,
|
||||||
|
rem,
|
||||||
}
|
}
|
||||||
|
@ -63,21 +63,21 @@ public class WasmRule extends TemporaryFolder {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void before() throws Throwable {
|
protected void before() throws Throwable {
|
||||||
super.before();
|
compile();
|
||||||
try {
|
}
|
||||||
wasmFile = newFile( "test.wasm" );
|
|
||||||
JWebAssembly wasm = new JWebAssembly();
|
|
||||||
for( Class<?> clazz : classes ) {
|
|
||||||
URL url = clazz.getResource( '/' + clazz.getName().replace( '.', '/' ) + ".class" );
|
|
||||||
wasm.addFile( url );
|
|
||||||
}
|
|
||||||
wasm.compileToBinary( wasmFile );
|
|
||||||
|
|
||||||
nodeScript = createScript( "nodetest.js" );
|
public void compile() throws IOException, WasmException {
|
||||||
spiderMonkeyScript = createScript( "SpiderMonkeyTest.js" );
|
create();
|
||||||
} catch( Exception ex ) {
|
wasmFile = newFile( "test.wasm" );
|
||||||
throwException( ex );
|
JWebAssembly wasm = new JWebAssembly();
|
||||||
|
for( Class<?> clazz : classes ) {
|
||||||
|
URL url = clazz.getResource( '/' + clazz.getName().replace( '.', '/' ) + ".class" );
|
||||||
|
wasm.addFile( url );
|
||||||
}
|
}
|
||||||
|
wasm.compileToBinary( wasmFile );
|
||||||
|
|
||||||
|
nodeScript = createScript( "nodetest.js" );
|
||||||
|
spiderMonkeyScript = createScript( "SpiderMonkeyTest.js" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
package de.inetsoftware.jwebassembly.err;
|
package de.inetsoftware.jwebassembly.err;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
@ -27,6 +30,7 @@ import org.junit.runners.Parameterized.Parameters;
|
|||||||
import org.webassembly.annotation.Export;
|
import org.webassembly.annotation.Export;
|
||||||
|
|
||||||
import de.inetsoftware.jwebassembly.ScriptEngine;
|
import de.inetsoftware.jwebassembly.ScriptEngine;
|
||||||
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.WasmRule;
|
import de.inetsoftware.jwebassembly.WasmRule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,4 +65,25 @@ public class RuntimeErrors {
|
|||||||
return Long.MAX_VALUE;
|
return Long.MAX_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void floatRem() throws IOException {
|
||||||
|
WasmRule wasm = new WasmRule( TestModulo.class );
|
||||||
|
try {
|
||||||
|
wasm.compile();
|
||||||
|
fail( "Floating modulo is not supported" );
|
||||||
|
} catch( WasmException ex ) {
|
||||||
|
assertTrue( ex.toString(), ex.getMessage().contains( "Modulo/Remainder" ) );
|
||||||
|
} finally {
|
||||||
|
wasm.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestModulo {
|
||||||
|
@Export
|
||||||
|
static float longReturn() {
|
||||||
|
float a = 3.4F;
|
||||||
|
return a % 2F;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,10 @@ public class MathOperations {
|
|||||||
addParam( list, script, "subLong" );
|
addParam( list, script, "subLong" );
|
||||||
addParam( list, script, "subFloat", 1F, 3.5F );
|
addParam( list, script, "subFloat", 1F, 3.5F );
|
||||||
addParam( list, script, "subDouble", 1.0, 3.5 );
|
addParam( list, script, "subDouble", 1.0, 3.5 );
|
||||||
|
addParam( list, script, "mulDivInt" );
|
||||||
|
addParam( list, script, "mulDivLong" );
|
||||||
|
addParam( list, script, "mulDivFloat" );
|
||||||
|
addParam( list, script, "mulDivDouble" );
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -136,5 +140,40 @@ public class MathOperations {
|
|||||||
static double subDouble( double a, double b ) {
|
static double subDouble( double a, double b ) {
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int mulDivInt() {
|
||||||
|
int a = 420;
|
||||||
|
a *= 3;
|
||||||
|
a /= -5;
|
||||||
|
a %= 37;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int mulDivLong() {
|
||||||
|
long a = -54321;
|
||||||
|
a *= 3;
|
||||||
|
a /= -5;
|
||||||
|
a %= 37;
|
||||||
|
return (int)a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static float mulDivFloat() {
|
||||||
|
float a = -54321F;
|
||||||
|
a *= 3F;
|
||||||
|
a /= -8F;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static double mulDivDouble() {
|
||||||
|
double a = -54321.0;
|
||||||
|
a *= 3F;
|
||||||
|
a /= -5F;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user