mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 10:44:47 +01:00
experimental code for arrays
This commit is contained in:
parent
8f365d629b
commit
74dcb4dc09
@ -31,6 +31,7 @@ import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.Member;
|
||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||
import de.inetsoftware.jwebassembly.module.ArrayOperator;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||
@ -778,4 +779,30 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
throw new Error( "Unknown block: " + op );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException {
|
||||
int opCode;
|
||||
switch(op) {
|
||||
case NEW:
|
||||
opCode = ARRAY_NEW;
|
||||
break;
|
||||
case GET:
|
||||
opCode = ARRAY_GET;
|
||||
break;
|
||||
case SET:
|
||||
opCode = ARRAY_SET;
|
||||
break;
|
||||
case LENGTH:
|
||||
opCode = ARRAY_LEN;
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown operator: " + op );
|
||||
}
|
||||
codeStream.writeOpCode( opCode );
|
||||
codeStream.writeValueType( valueType );
|
||||
}
|
||||
}
|
||||
|
@ -396,4 +396,23 @@ interface InstructionOpcodes {
|
||||
static final int I64_TRUNC_S_SAT_F64 = 0xFC06;
|
||||
|
||||
static final int I64_TRUNC_U_SAT_F64 = 0xFC07;
|
||||
|
||||
// === GC opcodes (unofficial, experimental) ===== https://github.com/lars-t-hansen/moz-gc-experiments/blob/master/version2.md
|
||||
|
||||
static final int STRUCT_NEW = 0xFC50;
|
||||
|
||||
static final int STRUCT_GET = 0xFC51;
|
||||
|
||||
static final int STRUCT_SET = 0xFC52;
|
||||
|
||||
static final int STRUCT_NARROW = 0xFC53;
|
||||
|
||||
|
||||
static final int ARRAY_NEW = 0xFC60;
|
||||
|
||||
static final int ARRAY_GET = 0xFC61;
|
||||
|
||||
static final int ARRAY_SET = 0xFC62;
|
||||
|
||||
static final int ARRAY_LEN = 0xFC63;
|
||||
}
|
||||
|
29
src/de/inetsoftware/jwebassembly/module/ArrayOperator.java
Normal file
29
src/de/inetsoftware/jwebassembly/module/ArrayOperator.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2018 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;
|
||||
|
||||
/**
|
||||
* Operation on Arrays.
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
public enum ArrayOperator {
|
||||
NEW,
|
||||
GET,
|
||||
SET,
|
||||
LENGTH,
|
||||
}
|
@ -131,7 +131,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 24: // dload
|
||||
addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedByte(), codePos );
|
||||
break;
|
||||
//TODO case 25: // aload
|
||||
case 25: // aload
|
||||
addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedByte(), codePos );
|
||||
break;
|
||||
case 26: // iload_0
|
||||
case 27: // iload_1
|
||||
case 28: // iload_2
|
||||
@ -156,11 +158,15 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 41: // dload_3
|
||||
addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos );
|
||||
break;
|
||||
//TODO case 42: //aload_0
|
||||
//TODO case 43: //aload_1
|
||||
//TODO case 44: //aload_2
|
||||
//TODO case 45: //aload_3
|
||||
//TODO case 46: // iaload
|
||||
case 42: //aload_0
|
||||
case 43: //aload_1
|
||||
case 44: //aload_2
|
||||
case 45: //aload_3
|
||||
addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos );
|
||||
break;
|
||||
case 46: // iaload
|
||||
addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos );
|
||||
break;
|
||||
//TODO case 47: // laload
|
||||
//TODO case 48: // faload
|
||||
//TODO case 49: // daload
|
||||
@ -180,7 +186,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 57: // dstore
|
||||
addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedByte(), codePos );
|
||||
break;
|
||||
//TODO case 58: // astore
|
||||
case 58: // astore
|
||||
addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedByte(), codePos );
|
||||
break;
|
||||
case 59: // istore_0
|
||||
case 60: // istore_1
|
||||
case 61: // istore_2
|
||||
@ -211,14 +219,16 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case 78: // astore_3
|
||||
addLoadStoreInstruction( ValueType.anyref, false, op - 75, codePos );
|
||||
break;
|
||||
//TODO case 79: // iastore
|
||||
//TODO case 80: // lastore
|
||||
//TODO case 81: // fastore
|
||||
//TODO case 82: // dastore
|
||||
//TODO case 83: // aastore
|
||||
//TODO case 84: // bastore
|
||||
//TODO case 85: // castore
|
||||
//TODO case 86: // sastore
|
||||
case 79: // iastore
|
||||
addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos );
|
||||
break;
|
||||
//TODO case 80: // lastore
|
||||
//TODO case 81: // fastore
|
||||
//TODO case 82: // dastore
|
||||
//TODO case 83: // aastore
|
||||
//TODO case 84: // bastore
|
||||
//TODO case 85: // castore
|
||||
//TODO case 86: // sastore
|
||||
case 87: // pop
|
||||
case 88: // pop2
|
||||
addBlockInstruction( WasmBlockOperator.DROP, null, codePos );
|
||||
@ -238,6 +248,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
case f64:
|
||||
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_f64", "(D)DD" ), codePos );
|
||||
break OP;
|
||||
case anyref:
|
||||
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_anyref", "(Ljava.lang.Object;)Ljava.lang.Object;Ljava.lang.Object;" ), codePos );
|
||||
break OP;
|
||||
}
|
||||
//$FALL-THROUGH$
|
||||
case 90: // dup_x1
|
||||
@ -518,9 +531,36 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
//TODO case 185: // invokeinterface
|
||||
//TODO case 186: // invokedynamic
|
||||
//TODO case 187: // new
|
||||
//TODO case 188: // newarray
|
||||
case 188: // newarray
|
||||
int typeValue = byteCode.readByte();
|
||||
switch( typeValue ) {
|
||||
case 4: // boolean
|
||||
case 5: // char
|
||||
type = ValueType.i32;
|
||||
break;
|
||||
case 6: //float
|
||||
type = ValueType.f32;
|
||||
break;
|
||||
case 7: //double
|
||||
type = ValueType.f64;
|
||||
break;
|
||||
case 8: //byte
|
||||
case 9: //short
|
||||
case 10: //int
|
||||
type = ValueType.i32;
|
||||
break;
|
||||
case 11: //long
|
||||
type = ValueType.i64;
|
||||
break;
|
||||
default:
|
||||
throw new WasmException( "Invalid Java byte code newarray: " + typeValue, byteCode.getLineNumber() );
|
||||
}
|
||||
addArrayInstruction( ArrayOperator.NEW, type, codePos );
|
||||
break;
|
||||
//TODO case 189: // anewarray
|
||||
//TODO case 190: // arraylength
|
||||
case 190: // arraylength
|
||||
addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos );
|
||||
break;
|
||||
//TODO case 191: // athrow
|
||||
//TODO case 192: // checkcast
|
||||
//TODO case 193: // instanceof
|
||||
|
@ -203,4 +203,16 @@ public abstract class ModuleWriter implements Closeable {
|
||||
* if any I/O error occur
|
||||
*/
|
||||
protected abstract void writeBlockCode( @Nonnull WasmBlockOperator op, @Nullable Object data ) throws IOException;
|
||||
|
||||
/**
|
||||
* Write an array operation.
|
||||
*
|
||||
* @param op
|
||||
* the operation
|
||||
* @param valueType
|
||||
* the resulting type
|
||||
* @throws IOException
|
||||
* if any I/O error occur
|
||||
*/
|
||||
protected abstract void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException;
|
||||
}
|
||||
|
@ -30,4 +30,7 @@ public class NativeHelperCode {
|
||||
|
||||
@WasmTextCode( signature = "(D)DD", value = "get_local 0 get_local 0 return" )
|
||||
native static void dup_f64();
|
||||
|
||||
@WasmTextCode( signature = "(Ljava.lang.Object;)Ljava.lang.Object;Ljava.lang.Object;", value = "get_local 0 get_local 0 return" )
|
||||
native static void dup_anyref();
|
||||
}
|
||||
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright 2018 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 javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
|
||||
/**
|
||||
* WasmInstruction for numeric operation.
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*
|
||||
*/
|
||||
class WasmArrayInstruction extends WasmInstruction {
|
||||
|
||||
private final ArrayOperator op;
|
||||
|
||||
private final ValueType valueType;
|
||||
|
||||
/**
|
||||
* Create an instance of numeric operation.
|
||||
*
|
||||
* @param numOp
|
||||
* the numeric operation
|
||||
* @param valueType
|
||||
* the type of the parameters
|
||||
* @param javaCodePos
|
||||
* the code position/offset in the Java method
|
||||
*/
|
||||
WasmArrayInstruction( @Nullable ArrayOperator op, @Nullable ValueType valueType, int javaCodePos ) {
|
||||
super( javaCodePos );
|
||||
this.op = op;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
||||
writer.writeArrayOperator( op, valueType );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
ValueType getPushValueType() {
|
||||
switch( op ) {
|
||||
case NEW:
|
||||
return ValueType.anyref;
|
||||
case GET:
|
||||
return valueType;
|
||||
case SET:
|
||||
return null;
|
||||
case LENGTH:
|
||||
return ValueType.i32;
|
||||
default:
|
||||
throw new WasmException( "Unknown array operation: " + op, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
int getPopCount() {
|
||||
switch( op ) {
|
||||
case NEW:
|
||||
case GET:
|
||||
case LENGTH:
|
||||
return 1;
|
||||
case SET:
|
||||
return 0;
|
||||
default:
|
||||
throw new WasmException( "Unknown array operation: " + op, -1 );
|
||||
}
|
||||
}
|
||||
}
|
@ -205,4 +205,18 @@ public abstract class WasmCodeBuilder {
|
||||
protected void addNopInstruction( int javaCodePos ) {
|
||||
instructions.add( new WasmNopInstruction( javaCodePos ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an array operation to the instruction list as marker on the code position.
|
||||
*
|
||||
* @param op
|
||||
* the operation
|
||||
* @param type
|
||||
* the array type
|
||||
* @param javaCodePos
|
||||
* the code position/offset in the Java method
|
||||
*/
|
||||
protected void addArrayInstruction( ArrayOperator op, ValueType type, int javaCodePos ) {
|
||||
instructions.add( new WasmArrayInstruction( op, type, javaCodePos ) );
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.classparser.Member;
|
||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||
import de.inetsoftware.jwebassembly.module.ArrayOperator;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||
@ -362,4 +363,27 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
methodOutput.append( name );
|
||||
inset += insetAfter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException {
|
||||
String operation;
|
||||
switch( op ) {
|
||||
case NEW:
|
||||
operation = "new";
|
||||
break;
|
||||
case GET:
|
||||
operation = "get";
|
||||
break;
|
||||
case SET:
|
||||
operation = "set";
|
||||
break;
|
||||
case LENGTH:
|
||||
operation = "len";
|
||||
break;
|
||||
default:
|
||||
throw new Error( "Unknown operator: " + op );
|
||||
}
|
||||
newline( methodOutput );
|
||||
methodOutput.append( "array." ).append( operation ).append( ' ' ).append( valueType );
|
||||
}
|
||||
}
|
||||
|
74
test/de/inetsoftware/jwebassembly/runtime/Arrays.java
Normal file
74
test/de/inetsoftware/jwebassembly/runtime/Arrays.java
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2018 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.runtime;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import de.inetsoftware.jwebassembly.ScriptEngine;
|
||||
import de.inetsoftware.jwebassembly.WasmRule;
|
||||
import de.inetsoftware.jwebassembly.api.annotation.Export;
|
||||
|
||||
public class Arrays extends AbstractBaseTest {
|
||||
|
||||
@ClassRule
|
||||
public static WasmRule rule = new WasmRule( TestClass.class );
|
||||
|
||||
public Arrays( ScriptEngine script, String method, Object[] params ) {
|
||||
super( rule, script, method, params );
|
||||
}
|
||||
|
||||
@Parameters( name = "{0}-{1}" )
|
||||
public static Collection<Object[]> data() {
|
||||
ArrayList<Object[]> list = new ArrayList<>();
|
||||
for( ScriptEngine[] val : ScriptEngine.testParams() ) {
|
||||
ScriptEngine script = val[0];
|
||||
addParam( list, script, "length" );
|
||||
addParam( list, script, "loop" );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void test() {
|
||||
super.test();
|
||||
}
|
||||
|
||||
static class TestClass {
|
||||
|
||||
@Export
|
||||
static int length() {
|
||||
return new int[5].length;
|
||||
}
|
||||
|
||||
@Export
|
||||
static int loop() {
|
||||
int[] data = {1,2,3};
|
||||
int sum = 0;
|
||||
for( int i : data ) {
|
||||
sum += i;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user