add support for the data types byte, short and char.

This commit is contained in:
Volker Berlin 2018-03-31 19:34:27 +02:00
parent 9c56f8b7ac
commit 7b66756066
3 changed files with 121 additions and 16 deletions

View File

@ -229,20 +229,17 @@ public abstract class ModuleWriter implements Closeable {
javaType = "object"; javaType = "object";
break; break;
case 'B': // byte case 'B': // byte
javaType = "byte";
break;
case 'C': // char case 'C': // char
javaType = "char"; case 'S': // short
break; case 'I': // int
writeMethodParam( kind, ValueType.i32 );
continue;
case 'D': // double case 'D': // double
writeMethodParam( kind, ValueType.f64 ); writeMethodParam( kind, ValueType.f64 );
continue; continue;
case 'F': // float case 'F': // float
writeMethodParam( kind, ValueType.f32 ); writeMethodParam( kind, ValueType.f32 );
continue; continue;
case 'I': // int
writeMethodParam( kind, ValueType.i32 );
continue;
case 'J': // long case 'J': // long
writeMethodParam( kind, ValueType.i64 ); writeMethodParam( kind, ValueType.i64 );
continue; continue;
@ -335,12 +332,12 @@ public abstract class ModuleWriter implements Closeable {
case 165: // if_acmpeq case 165: // if_acmpeq
case 166: // if_acmpne case 166: // if_acmpne
int startPosition = byteCode.getCodePosition() + 2; int startPosition = byteCode.getCodePosition() + 2;
int offset = byteCode.readUnsignedShort(); int offset = byteCode.readShort();
branchManager.start( BlockOperator.IF, startPosition, offset - 3 ); branchManager.start( BlockOperator.IF, startPosition, offset - 3 );
break; break;
case 167: // goto case 167: // goto
startPosition = byteCode.getCodePosition() - 1; startPosition = byteCode.getCodePosition() - 1;
offset = byteCode.readUnsignedShort(); offset = byteCode.readShort();
branchManager.start( BlockOperator.GOTO, startPosition, offset ); branchManager.start( BlockOperator.GOTO, startPosition, offset );
break; break;
} }
@ -367,6 +364,8 @@ public abstract class ModuleWriter implements Closeable {
branchManager.handle( byteCode, this ); branchManager.handle( byteCode, this );
int op = byteCode.readUnsignedByte(); int op = byteCode.readUnsignedByte();
switch( op ) { switch( op ) {
case 0: // nop
return;
case 2: // iconst_m1 case 2: // iconst_m1
case 3: // iconst_0 case 3: // iconst_0
case 4: // iconst_1 case 4: // iconst_1
@ -398,9 +397,23 @@ public abstract class ModuleWriter implements Closeable {
case 18: // ldc case 18: // ldc
writeConst( constantPool.get( byteCode.readUnsignedByte() ) ); writeConst( constantPool.get( byteCode.readUnsignedByte() ) );
break; break;
case 19: // ldc_w
case 20: // ldc2_w case 20: // ldc2_w
writeConst( constantPool.get( byteCode.readUnsignedShort() ) ); writeConst( constantPool.get( byteCode.readUnsignedShort() ) );
break; break;
case 21: // iload
writeLoadStore( true, ValueType.i32, byteCode.readUnsignedByte() );
break;
case 22: // lload
writeLoadStore( true, ValueType.i64, byteCode.readUnsignedByte() );
break;
case 23: // fload
writeLoadStore( true, ValueType.f32, byteCode.readUnsignedByte() );
break;
case 24: // dload
writeLoadStore( true, ValueType.f64, byteCode.readUnsignedByte() );
break;
//TODO case 25: // aload
case 26: // iload_0 case 26: // iload_0
case 27: // iload_1 case 27: // iload_1
case 28: // iload_2 case 28: // iload_2
@ -425,6 +438,19 @@ public abstract class ModuleWriter implements Closeable {
case 41: // dload_3 case 41: // dload_3
writeLoadStore( true, ValueType.f64, op - 38 ); writeLoadStore( true, ValueType.f64, op - 38 );
break; break;
case 54: // istore
writeLoadStore( false, ValueType.i32, byteCode.readUnsignedByte() );
break;
case 55: // lstore
writeLoadStore( false, ValueType.i64, byteCode.readUnsignedByte() );
break;
case 56: // fstore
writeLoadStore( false, ValueType.f32, byteCode.readUnsignedByte() );
break;
case 57: // dstore
writeLoadStore( false, ValueType.f64, byteCode.readUnsignedByte() );
break;
//TODO case 58: // astore
case 59: // istore_0 case 59: // istore_0
case 60: // istore_1 case 60: // istore_1
case 61: // istore_2 case 61: // istore_2
@ -552,9 +578,28 @@ public abstract class ModuleWriter implements Closeable {
writeNumericOperator( NumericOperator.add, ValueType.i32); writeNumericOperator( NumericOperator.add, ValueType.i32);
writeLoadStore( false, ValueType.i32, idx ); writeLoadStore( false, ValueType.i32, idx );
break; break;
case 133: // i2l
writeCast( ValueTypeConvertion.i2l );
break;
case 136: // l2i case 136: // l2i
writeCast( ValueTypeConvertion.l2i ); writeCast( ValueTypeConvertion.l2i );
break; break;
case 145: // i2b
writeConstInt( 24 );
writeNumericOperator( NumericOperator.shl, ValueType.i32 );
writeConstInt( 24 );
writeNumericOperator( NumericOperator.shr_s, ValueType.i32 );
break;
case 146: // i2c
writeConstInt( 0xFFFF );
writeNumericOperator( NumericOperator.and, ValueType.i32 );
break;
case 147: // i2s
writeConstInt( 16 );
writeNumericOperator( NumericOperator.shl, ValueType.i32 );
writeConstInt( 16 );
writeNumericOperator( NumericOperator.shr_s, ValueType.i32 );
break;
case 153: // ifeq case 153: // ifeq
opIfCondition( NumericOperator.ne, byteCode ); opIfCondition( NumericOperator.ne, byteCode );
break; break;
@ -589,7 +634,7 @@ public abstract class ModuleWriter implements Closeable {
writeFunctionCall( method.getConstantClass().getName() + '.' + method.getName() + method.getType() ); writeFunctionCall( method.getConstantClass().getName() + '.' + method.getName() + method.getType() );
break; break;
default: default:
throw new WasmException( "Unimplemented byte code operation: " + op, sourceFile, lineNumber ); throw new WasmException( "Unimplemented Java byte code operation: " + op, sourceFile, lineNumber );
} }
} }
} catch( Exception ex ) { } catch( Exception ex ) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2017 Volker Berlin (i-net software) * Copyright 2017 - 2018 Volker Berlin (i-net software)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -139,6 +139,15 @@ public class WasmRule extends TemporaryFolder {
for( int i = 0; i < types.length; i++ ) { for( int i = 0; i < types.length; i++ ) {
Class<?> type = params[i].getClass(); Class<?> type = params[i].getClass();
switch( type.getName() ) { switch( type.getName() ) {
case "java.lang.Byte":
type = byte.class;
break;
case "java.lang.Short":
type = short.class;
break;
case "java.lang.Character":
type = char.class;
break;
case "java.lang.Integer": case "java.lang.Integer":
type = int.class; type = int.class;
break; break;
@ -167,7 +176,15 @@ public class WasmRule extends TemporaryFolder {
} }
method.setAccessible( true ); method.setAccessible( true );
expected = method.invoke( null, params ); expected = method.invoke( null, params );
if( expected instanceof Character ) { // WASM does not support char that it is number
expected = new Integer( ((Character)expected).charValue() );
}
for( int i = 0; i < params.length; i++ ) {
if( params[i] instanceof Character ) {
params[i] = new Integer( ((Character)params[i]).charValue() );
}
}
String actual = evalWasm( script, methodName, params ); String actual = evalWasm( script, methodName, params );
assertEquals( String.valueOf( expected ), actual ); assertEquals( String.valueOf( expected ), actual );
} catch( Throwable ex ) { } catch( Throwable ex ) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2017 Volker Berlin (i-net software) * Copyright 2017 - 2018 Volker Berlin (i-net software)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -61,6 +61,10 @@ public class MathOperations extends AbstractBaseTest {
addParam( list, script, "mulDivDouble" ); addParam( list, script, "mulDivDouble" );
addParam( list, script, "intBits" ); addParam( list, script, "intBits" );
addParam( list, script, "longBits" ); addParam( list, script, "longBits" );
addParam( list, script, "byteInc", (byte)127 );
addParam( list, script, "byteDec", (byte)-128 );
addParam( list, script, "shortInc", (short)-32768 );
addParam( list, script, "charOp", (char)0xFFFF );
} }
return list; return list;
} }
@ -84,8 +88,11 @@ public class MathOperations extends AbstractBaseTest {
@Export @Export
static int addInt( int a, int b ) { static int addInt( int a, int b ) {
int c = 1234567;
int d = -1234567;
int e = -1;
b++; b++;
return a + b; return a + b + c + d + e;
} }
@Export @Export
@ -97,12 +104,18 @@ public class MathOperations extends AbstractBaseTest {
@Export @Export
static float addFloat( float a, float b ) { static float addFloat( float a, float b ) {
return a + b; float c = -1;
float d = 1234;
float e = 1.25F;
return a + b + c + d + e;
} }
@Export @Export
static double addDouble( double a, double b ) { static double addDouble( double a, double b ) {
return a + b; double c = -1;
double d = 1234;
double e = 1.25;
return a + b + c + d + e;
} }
@Export @Export
@ -114,8 +127,11 @@ public class MathOperations extends AbstractBaseTest {
static int subLong() { static int subLong() {
long a = -1L; long a = -1L;
long b = 3L; long b = 3L;
long c = -1L;
long d = 1234L;
int e = 3;
a--; a--;
return (int)(a - b); return (int)(a - b - c - d + e);
} }
@Export @Export
@ -186,5 +202,32 @@ public class MathOperations extends AbstractBaseTest {
return (int)(a ^ (b >> 32)); return (int)(a ^ (b >> 32));
} }
@Export
static byte byteInc( byte a ) {
a++;
a += 2;
return a;
}
@Export
static byte byteDec( byte a ) {
a--;
a -= 2;
return a;
}
@Export
static short shortInc( short a ) {
a++;
a += 2;
return a;
}
@Export
static char charOp( char a ) {
a++;
a += 60;
return a;
}
} }
} }