wasm: add support for array.copy instruction

This commit is contained in:
Alexey Andreev 2024-08-03 19:55:16 +02:00
parent 98cd2efc0f
commit 6af7250e3b
11 changed files with 189 additions and 0 deletions

View File

@ -0,0 +1,103 @@
/*
* Copyright 2024 Alexey Andreev.
*
* 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 org.teavm.backend.wasm.model.expression;
import org.teavm.backend.wasm.model.WasmArray;
public class WasmArrayCopy extends WasmExpression {
private WasmArray targetArrayType;
private WasmExpression targetArray;
private WasmExpression targetIndex;
private WasmArray sourceArrayType;
private WasmExpression sourceArray;
private WasmExpression sourceIndex;
private WasmExpression size;
public WasmArrayCopy(
WasmArray targetArrayType, WasmExpression targetArray, WasmExpression targetIndex,
WasmArray sourceArrayType, WasmExpression sourceArray, WasmExpression sourceIndex,
WasmExpression size
) {
this.targetArrayType = targetArrayType;
this.targetArray = targetArray;
this.targetIndex = targetIndex;
this.sourceArrayType = sourceArrayType;
this.sourceArray = sourceArray;
this.sourceIndex = sourceIndex;
this.size = size;
}
public WasmArray getTargetArrayType() {
return targetArrayType;
}
public void setTargetArrayType(WasmArray targetArrayType) {
this.targetArrayType = targetArrayType;
}
public WasmExpression getTargetArray() {
return targetArray;
}
public void setTargetArray(WasmExpression targetArray) {
this.targetArray = targetArray;
}
public WasmExpression getTargetIndex() {
return targetIndex;
}
public void setTargetIndex(WasmExpression targetIndex) {
this.targetIndex = targetIndex;
}
public WasmArray getSourceArrayType() {
return sourceArrayType;
}
public void setSourceArrayType(WasmArray sourceArrayType) {
this.sourceArrayType = sourceArrayType;
}
public WasmExpression getSourceArray() {
return sourceArray;
}
public void setSourceArray(WasmExpression sourceArray) {
this.sourceArray = sourceArray;
}
public WasmExpression getSourceIndex() {
return sourceIndex;
}
public void setSourceIndex(WasmExpression sourceIndex) {
this.sourceIndex = sourceIndex;
}
public WasmExpression getSize() {
return size;
}
public void setSize(WasmExpression size) {
this.size = size;
}
@Override
public void acceptVisitor(WasmExpressionVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -296,6 +296,15 @@ public class WasmDefaultExpressionVisitor implements WasmExpressionVisitor {
expression.getInstance().acceptVisitor(this);
}
@Override
public void visit(WasmArrayCopy expression) {
expression.getTargetArray().acceptVisitor(this);
expression.getTargetIndex().acceptVisitor(this);
expression.getSourceArray().acceptVisitor(this);
expression.getSourceIndex().acceptVisitor(this);
expression.getSize().acceptVisitor(this);
}
@Override
public void visit(WasmFunctionReference expression) {
}

View File

@ -112,5 +112,7 @@ public interface WasmExpressionVisitor {
void visit(WasmArrayLength expression);
void visit(WasmArrayCopy expression);
void visit(WasmFunctionReference expression);
}

View File

@ -357,6 +357,24 @@ public class WasmReplacingExpressionVisitor implements WasmExpressionVisitor {
expression.setInstance(mapper.apply(expression.getInstance()));
}
@Override
public void visit(WasmArrayCopy expression) {
expression.getSourceArray().acceptVisitor(this);
expression.setSourceArray(mapper.apply(expression.getSourceArray()));
expression.getSourceIndex().acceptVisitor(this);
expression.setSourceIndex(mapper.apply(expression.getSourceIndex()));
expression.getTargetArray().acceptVisitor(this);
expression.setTargetArray(mapper.apply(expression.getTargetArray()));
expression.getTargetIndex().acceptVisitor(this);
expression.setTargetIndex(mapper.apply(expression.getTargetIndex()));
expression.getSize().acceptVisitor(this);
expression.setSize(mapper.apply(expression.getSize()));
}
@Override
public void visit(WasmFunctionReference expression) {
}

View File

@ -27,6 +27,7 @@ import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmStorageType;
import org.teavm.backend.wasm.model.WasmStructure;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmArraySet;
import org.teavm.backend.wasm.model.expression.WasmCallReference;
@ -156,6 +157,13 @@ public class UnusedTypeElimination {
super.visit(expression);
use(expression.getType());
}
@Override
public void visit(WasmArrayCopy expression) {
super.visit(expression);
use(expression.getSourceArrayType());
use(expression.getTargetArrayType());
}
};
private WasmCompositeTypeVisitor typeVisitor = new WasmDefaultCompositeTypeVisitor() {

View File

@ -159,6 +159,9 @@ public interface CodeListener {
default void arraySet(int typeIndex) {
}
default void arrayCopy(int targetTypeIndex, int sourceTypeIndex) {
}
default void getGlobal(int globalIndex) {
}

View File

@ -723,6 +723,10 @@ public class CodeSectionParser {
codeListener.opcode(Opcode.ARRAY_LENGTH);
return true;
case 17:
codeListener.arrayCopy(readLEB(), readLEB());
return true;
case 23:
codeListener.cast(readHeapType());
return true;

View File

@ -25,6 +25,7 @@ import org.teavm.backend.wasm.debug.DebugLines;
import org.teavm.backend.wasm.generate.DwarfGenerator;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
@ -1142,6 +1143,21 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
popLocation();
}
@Override
public void visit(WasmArrayCopy expression) {
pushLocation(expression);
expression.getTargetArray().acceptVisitor(this);
expression.getTargetIndex().acceptVisitor(this);
expression.getSourceArray().acceptVisitor(this);
expression.getSourceIndex().acceptVisitor(this);
expression.getSize().acceptVisitor(this);
writer.writeByte(0xfb);
writer.writeByte(17);
writer.writeLEB(module.types.indexOf(expression.getTargetArrayType()));
writer.writeLEB(module.types.indexOf(expression.getSourceArrayType()));
popLocation();
}
@Override
public void visit(WasmFunctionReference expression) {
pushLocation(expression);

View File

@ -27,6 +27,7 @@ import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmNumType;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
@ -1209,6 +1210,11 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
unsupported();
}
@Override
public void visit(WasmArrayCopy expression) {
unsupported();
}
@Override
public void visit(WasmFunctionReference expression) {
unsupported();

View File

@ -23,6 +23,7 @@ import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmNumType;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
@ -791,6 +792,19 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
close();
}
@Override
public void visit(WasmArrayCopy expression) {
open().append("array.copy");
append(" ").append(typeName(expression.getTargetArrayType()));
append(" ").append(typeName(expression.getSourceArrayType()));
line(expression.getTargetArray());
line(expression.getTargetIndex());
line(expression.getSourceArray());
line(expression.getSourceIndex());
line(expression.getSize());
close();
}
@Override
public void visit(WasmFunctionReference expression) {
open().append("ref.func ").append(" $" + module.functions.indexOf(expression.getFunction()));

View File

@ -16,6 +16,7 @@
package org.teavm.backend.wasm.render;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
@ -317,6 +318,11 @@ public class WasmTypeInference implements WasmExpressionVisitor {
result = WasmType.INT32;
}
@Override
public void visit(WasmArrayCopy expression) {
result = null;
}
@Override
public void visit(WasmFunctionReference expression) {
result = expression.getFunction().getType().getReference();