wasm gc: implement creation of multidimensional arrays

This commit is contained in:
Alexey Andreev 2024-09-18 20:34:29 +02:00
parent 34bba2a4a5
commit 10805ed0dd
15 changed files with 138 additions and 53 deletions

View File

@ -172,7 +172,6 @@ public class ServiceLoaderWasmGCSupport implements WasmGCCustomGeneratorFactory
function.setReferenced(true); function.setReferenced(true);
function.setName(context.names().topLevel("teavm@emptyServicesInitializer")); function.setName(context.names().topLevel("teavm@emptyServicesInitializer"));
context.module().functions.add(function); context.module().functions.add(function);
function.getBody().add(new WasmReturn());
return function; return function;
} }
} }

View File

@ -27,7 +27,6 @@ import org.teavm.backend.wasm.model.expression.WasmExpression;
import org.teavm.backend.wasm.model.expression.WasmFunctionReference; import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
import org.teavm.backend.wasm.model.expression.WasmGetGlobal; import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
import org.teavm.backend.wasm.model.expression.WasmGetLocal; import org.teavm.backend.wasm.model.expression.WasmGetLocal;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmSetGlobal; import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
import org.teavm.backend.wasm.runtime.WasmGCSupport; import org.teavm.backend.wasm.runtime.WasmGCSupport;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -51,7 +50,6 @@ public class WasmGCModuleGenerator {
private void fillInitializer() { private void fillInitializer() {
declarationsGenerator.contributeToInitializer(initializer); declarationsGenerator.contributeToInitializer(initializer);
initializer.getBody().add(new WasmReturn());
} }
public WasmFunction generateMainFunction(String entryPoint) { public WasmFunction generateMainFunction(String entryPoint) {
@ -66,7 +64,6 @@ public class WasmGCModuleGenerator {
var callToMainFunction = new WasmCall(mainFunction, new WasmGetLocal(argsLocal)); var callToMainFunction = new WasmCall(mainFunction, new WasmGetLocal(argsLocal));
mainFunctionCaller.getBody().add(callToMainFunction); mainFunctionCaller.getBody().add(callToMainFunction);
mainFunctionCaller.getBody().add(new WasmReturn());
return mainFunctionCaller; return mainFunctionCaller;
} }
@ -76,7 +73,7 @@ public class WasmGCModuleGenerator {
WasmGCSupport.class, "createStringBuilder", StringBuilder.class)); WasmGCSupport.class, "createStringBuilder", StringBuilder.class));
var caller = new WasmFunction(function.getType()); var caller = new WasmFunction(function.getType());
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function))); caller.getBody().add(new WasmCall(function));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -88,7 +85,7 @@ public class WasmGCModuleGenerator {
var sizeLocal = new WasmLocal(WasmType.INT32, "length"); var sizeLocal = new WasmLocal(WasmType.INT32, "length");
caller.add(sizeLocal); caller.add(sizeLocal);
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(sizeLocal)))); caller.getBody().add(new WasmCall(function, new WasmGetLocal(sizeLocal)));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -105,7 +102,6 @@ public class WasmGCModuleGenerator {
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmDrop(new WasmCall(function, new WasmGetLocal(stringBuilderLocal), caller.getBody().add(new WasmDrop(new WasmCall(function, new WasmGetLocal(stringBuilderLocal),
new WasmGetLocal(codeLocal)))); new WasmGetLocal(codeLocal))));
caller.getBody().add(new WasmReturn());
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -119,7 +115,7 @@ public class WasmGCModuleGenerator {
var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder"); var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder");
caller.add(stringBuilderLocal); caller.add(stringBuilderLocal);
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringBuilderLocal)))); caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringBuilderLocal)));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -137,8 +133,8 @@ public class WasmGCModuleGenerator {
caller.add(indexLocal); caller.add(indexLocal);
caller.add(valueLocal); caller.add(valueLocal);
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(arrayLocal), caller.getBody().add(new WasmCall(function, new WasmGetLocal(arrayLocal),
new WasmGetLocal(indexLocal), new WasmGetLocal(valueLocal)))); new WasmGetLocal(indexLocal), new WasmGetLocal(valueLocal)));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -151,7 +147,7 @@ public class WasmGCModuleGenerator {
var stringLocal = new WasmLocal(stringType, "string"); var stringLocal = new WasmLocal(stringType, "string");
caller.add(stringLocal); caller.add(stringLocal);
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringLocal)))); caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringLocal)));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }
@ -166,8 +162,8 @@ public class WasmGCModuleGenerator {
caller.add(stringLocal); caller.add(stringLocal);
caller.add(indexLocal); caller.add(indexLocal);
caller.getBody().add(callInitializer()); caller.getBody().add(callInitializer());
caller.getBody().add(new WasmReturn(new WasmCall(function, new WasmGetLocal(stringLocal), caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringLocal),
new WasmGetLocal(indexLocal)))); new WasmGetLocal(indexLocal)));
declarationsGenerator.module.functions.add(caller); declarationsGenerator.module.functions.add(caller);
return caller; return caller;
} }

View File

@ -784,7 +784,7 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
} }
@Override @Override
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType itemType, protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
Supplier<List<WasmExpression>> dimensions, TextLocation location) { Supplier<List<WasmExpression>> dimensions, TextLocation location) {
int dimensionList = -1; int dimensionList = -1;
var dimensionsValue = dimensions.get(); var dimensionsValue = dimensions.get();
@ -797,7 +797,7 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
WasmInt32Subtype.INT32)); WasmInt32Subtype.INT32));
} }
int classPointer = classGenerator.getClassPointer(itemType); int classPointer = classGenerator.getClassPointer(arrayType);
var allocFunction = context.functions().forStaticMethod(new MethodReference(Allocator.class, var allocFunction = context.functions().forStaticMethod(new MethodReference(Allocator.class,
"allocateMultiArray", RuntimeClass.class, Address.class, int.class, RuntimeArray.class)); "allocateMultiArray", RuntimeClass.class, Address.class, int.class, RuntimeArray.class));
var call = new WasmCall(allocFunction); var call = new WasmCall(allocFunction);

View File

@ -1041,7 +1041,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
protected abstract void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location, protected abstract void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
WasmLocal local, List<WasmExpression> target); WasmLocal local, List<WasmExpression> target);
protected abstract WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType itemType, protected abstract WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
Supplier<List<WasmExpression>> dimensions, TextLocation location); Supplier<List<WasmExpression>> dimensions, TextLocation location);
@Override @Override
@ -1107,9 +1107,6 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
callSiteId.generateRegister(block.getBody(), expr.getLocation()); callSiteId.generateRegister(block.getBody(), expr.getLocation());
var arrayType = expr.getType(); var arrayType = expr.getType();
for (var dimension : expr.getDimensions()) {
arrayType = ValueType.arrayOf(arrayType);
}
block.setType(mapType(arrayType)); block.setType(mapType(arrayType));
var call = allocateMultiArray(block.getBody(), expr.getType(), () -> { var call = allocateMultiArray(block.getBody(), expr.getType(), () -> {
var wasmDimensions = new ArrayList<WasmExpression>(); var wasmDimensions = new ArrayList<WasmExpression>();

View File

@ -19,6 +19,7 @@ import com.carrotsearch.hppc.ObjectIntHashMap;
import com.carrotsearch.hppc.ObjectIntMap; import com.carrotsearch.hppc.ObjectIntMap;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -67,7 +68,6 @@ import org.teavm.backend.wasm.model.expression.WasmIntBinary;
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation; import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
import org.teavm.backend.wasm.model.expression.WasmIntType; import org.teavm.backend.wasm.model.expression.WasmIntType;
import org.teavm.backend.wasm.model.expression.WasmNullConstant; import org.teavm.backend.wasm.model.expression.WasmNullConstant;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmSetGlobal; import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
import org.teavm.backend.wasm.model.expression.WasmSetLocal; import org.teavm.backend.wasm.model.expression.WasmSetLocal;
import org.teavm.backend.wasm.model.expression.WasmSignedType; import org.teavm.backend.wasm.model.expression.WasmSignedType;
@ -355,7 +355,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var req = metadataRequirements.getInfo(type); var req = metadataRequirements.getInfo(type);
if (req != null) { if (req != null) {
if (req.newArray()) { if (req.newArray()) {
classInfo.initArrayFunction = getArrayConstructor(ValueType.arrayOf(classInfo.getValueType())); classInfo.initArrayFunction = getArrayConstructor(classInfo.getValueType(), 1);
classInfo.initArrayFunction.setReferenced(true); classInfo.initArrayFunction.setReferenced(true);
} }
if (req.isAssignable()) { if (req.isAssignable()) {
@ -369,12 +369,23 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
} }
@Override @Override
public WasmFunction getArrayConstructor(ValueType.Array type) { public WasmFunction getArrayConstructor(ValueType type, int depth) {
var arrayInfo = getClassInfo(type); var arrayInfo = getClassInfo(type);
if (arrayInfo.newArrayFunction == null) { if (arrayInfo.newArrayFunctions == null) {
arrayInfo.newArrayFunction = newArrayGenerator.generateNewArrayFunction(type.getItemType()); arrayInfo.newArrayFunctions = new ArrayList<>();
} }
return arrayInfo.newArrayFunction; if (depth >= arrayInfo.newArrayFunctions.size()) {
arrayInfo.newArrayFunctions.addAll(Collections.nCopies(
depth - arrayInfo.newArrayFunctions.size() + 1, null));
}
var function = arrayInfo.newArrayFunctions.get(depth);
if (function == null) {
function = depth == 1
? newArrayGenerator.generateNewArrayFunction(type)
: newArrayGenerator.generateNewMultiArrayFunction(type, depth);
arrayInfo.newArrayFunctions.set(depth, function);
}
return function;
} }
public int getClassTagOffset() { public int getClassTagOffset() {
@ -631,7 +642,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
} }
} }
function.getBody().add(new WasmReturn(copy)); function.getBody().add(copy);
return function; return function;
} }
@ -697,7 +708,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var castObject = new WasmCast(new WasmGetLocal(objectLocal), objectStructure.getNonNullReference()); var castObject = new WasmCast(new WasmGetLocal(objectLocal), objectStructure.getNonNullReference());
var arrayField = new WasmStructGet(objectStructure, castObject, ARRAY_DATA_FIELD_OFFSET); var arrayField = new WasmStructGet(objectStructure, castObject, ARRAY_DATA_FIELD_OFFSET);
var result = new WasmArrayLength(arrayField); var result = new WasmArrayLength(arrayField);
function.getBody().add(new WasmReturn(result)); function.getBody().add(result);
return function; return function;
} }
@ -728,7 +739,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var array = new WasmCast(new WasmGetLocal(objectLocal), arrayStruct.getNonNullReference()); var array = new WasmCast(new WasmGetLocal(objectLocal), arrayStruct.getNonNullReference());
var arrayData = new WasmStructGet(arrayStruct, array, ARRAY_DATA_FIELD_OFFSET); var arrayData = new WasmStructGet(arrayStruct, array, ARRAY_DATA_FIELD_OFFSET);
var result = new WasmArrayGet(arrayDataType, arrayData, new WasmGetLocal(indexLocal)); var result = new WasmArrayGet(arrayDataType, arrayData, new WasmGetLocal(indexLocal));
arrayGetObjectFunction.getBody().add(new WasmReturn(result)); arrayGetObjectFunction.getBody().add(result);
} }
return arrayGetObjectFunction; return arrayGetObjectFunction;
} }
@ -797,7 +808,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var method = new MethodReference(wrapperType, "valueOf", primitiveType, wrapperType); var method = new MethodReference(wrapperType, "valueOf", primitiveType, wrapperType);
var wrapFunction = functionProvider.forStaticMethod(method); var wrapFunction = functionProvider.forStaticMethod(method);
var castResult = new WasmCall(wrapFunction, result); var castResult = new WasmCall(wrapFunction, result);
function.getBody().add(new WasmReturn(castResult)); function.getBody().add(castResult);
return function; return function;
} }
@ -842,7 +853,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
call.getArguments().add(new WasmGetLocal(params[i])); call.getArguments().add(new WasmGetLocal(params[i]));
wrapperFunction.add(params[i]); wrapperFunction.add(params[i]);
} }
wrapperFunction.getBody().add(new WasmReturn(call)); wrapperFunction.getBody().add(call);
function = wrapperFunction; function = wrapperFunction;
} }
function.setReferenced(true); function.setReferenced(true);
@ -1441,7 +1452,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var block = new WasmBlock(false); var block = new WasmBlock(false);
block.setType(enumArrayStruct.getReference()); block.setType(enumArrayStruct.getReference());
util.allocateArrayWithElements(ValueType.parse(Enum.class), () -> fields, null, null, block.getBody()); util.allocateArrayWithElements(ValueType.parse(Enum.class), () -> fields, null, null, block.getBody());
function.getBody().add(new WasmReturn(block)); function.getBody().add(block);
tempVars.release(local); tempVars.release(local);
return function; return function;

View File

@ -32,7 +32,7 @@ public class WasmGCClassInfo {
WasmGlobal pointer; WasmGlobal pointer;
WasmGlobal initializerPointer; WasmGlobal initializerPointer;
Consumer<List<WasmExpression>> initializer; Consumer<List<WasmExpression>> initializer;
WasmFunction newArrayFunction; List<WasmFunction> newArrayFunctions;
WasmFunction initArrayFunction; WasmFunction initArrayFunction;
WasmFunction supertypeFunction; WasmFunction supertypeFunction;

View File

@ -35,7 +35,7 @@ public interface WasmGCClassInfoProvider {
WasmGlobal getStaticFieldLocation(FieldReference fieldRef); WasmGlobal getStaticFieldLocation(FieldReference fieldRef);
WasmFunction getArrayConstructor(ValueType.Array type); WasmFunction getArrayConstructor(ValueType type, int depth);
int getVirtualMethodsOffset(); int getVirtualMethodsOffset();

View File

@ -15,19 +15,33 @@
*/ */
package org.teavm.backend.wasm.generate.gc.classes; package org.teavm.backend.wasm.generate.gc.classes;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import org.teavm.backend.wasm.WasmFunctionTypes; import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.generate.TemporaryVariablePool; import org.teavm.backend.wasm.generate.TemporaryVariablePool;
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider; import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil; import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
import org.teavm.backend.wasm.model.WasmArray;
import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.model.WasmFunctionType; import org.teavm.backend.wasm.model.WasmFunctionType;
import org.teavm.backend.wasm.model.WasmLocal; import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmModule; import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmType; import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmArraySet;
import org.teavm.backend.wasm.model.expression.WasmBlock;
import org.teavm.backend.wasm.model.expression.WasmBranch;
import org.teavm.backend.wasm.model.expression.WasmCall;
import org.teavm.backend.wasm.model.expression.WasmExpression;
import org.teavm.backend.wasm.model.expression.WasmGetLocal; import org.teavm.backend.wasm.model.expression.WasmGetLocal;
import org.teavm.backend.wasm.model.expression.WasmReturn; import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
import org.teavm.backend.wasm.model.expression.WasmIntType;
import org.teavm.backend.wasm.model.expression.WasmIntUnary;
import org.teavm.backend.wasm.model.expression.WasmIntUnaryOperation;
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
import org.teavm.backend.wasm.model.expression.WasmStructGet;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
class WasmGCNewArrayFunctionGenerator { class WasmGCNewArrayFunctionGenerator {
@ -66,7 +80,75 @@ class WasmGCNewArrayFunctionGenerator {
var targetVar = new WasmLocal(classInfo.getType(), "result"); var targetVar = new WasmLocal(classInfo.getType(), "result");
function.add(targetVar); function.add(targetVar);
genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody()); genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar))); function.getBody().add(new WasmGetLocal(targetVar));
});
return function;
}
WasmFunction generateNewMultiArrayFunction(ValueType itemType, int depth) {
var arrayType = itemType;
for (var i = 0; i < depth; ++i) {
arrayType = ValueType.arrayOf(arrayType);
}
var classInfo = classInfoProvider.getClassInfo(arrayType);
var parameterTypes = new WasmType[depth];
Arrays.fill(parameterTypes, WasmType.INT32);
var functionType = functionTypes.of(classInfo.getType(), parameterTypes);
var function = new WasmFunction(functionType);
function.setName(names.topLevel(names.suggestForType(arrayType) + "@new:" + depth));
module.functions.add(function);
var finalArrayType = arrayType;
queue.add(() -> {
var dimensionLocals = new WasmLocal[depth];
for (var i = 0; i < depth; ++i) {
var dimensionLocal = new WasmLocal(WasmType.INT32, "dim" + i);
dimensionLocals[i] = dimensionLocal;
function.add(dimensionLocal);
}
var indexLocal = new WasmLocal(WasmType.INT32, "index");
function.add(indexLocal);
var dataField = classInfo.getStructure().getFields().get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET);
var dataFieldTypeRef = (WasmType.CompositeReference) dataField.getUnpackedType();
var dataArray = (WasmArray) dataFieldTypeRef.composite;
var dataLocal = new WasmLocal(dataArray.getReference(), "data");
function.add(dataLocal);
var resultVar = new WasmLocal(classInfo.getType(), "result");
function.add(resultVar);
var arrayItemType = ((ValueType.Array) finalArrayType).getItemType();
var allocFunction = classInfoProvider.getArrayConstructor(arrayItemType, 1);
function.getBody().add(new WasmSetLocal(resultVar, new WasmCall(allocFunction,
new WasmGetLocal(dimensionLocals[0]))));
function.getBody().add(new WasmSetLocal(dataLocal, new WasmStructGet(classInfo.getStructure(),
new WasmGetLocal(resultVar), WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET)));
var zeroGuard = new WasmBlock(false);
function.getBody().add(zeroGuard);
zeroGuard.getBody().add(new WasmBranch(new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ,
new WasmGetLocal(dimensionLocals[0])), zeroGuard));
var loop = new WasmBlock(true);
zeroGuard.getBody().add(loop);
var itemFunction = classInfoProvider.getArrayConstructor(itemType, depth - 1);
var args = new WasmExpression[depth - 1];
for (var i = 0; i < args.length; ++i) {
args[i] = new WasmGetLocal(dimensionLocals[i + 1]);
}
loop.getBody().add(new WasmArraySet(dataArray, new WasmGetLocal(dataLocal), new WasmGetLocal(indexLocal),
new WasmCall(itemFunction, args)));
var incrementIndex = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
new WasmGetLocal(indexLocal), new WasmInt32Constant(1));
loop.getBody().add(new WasmSetLocal(indexLocal, incrementIndex));
var continueCondition = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.LT_UNSIGNED,
new WasmGetLocal(indexLocal), new WasmGetLocal(dimensionLocals[0]));
loop.getBody().add(new WasmBranch(continueCondition, loop));
function.getBody().add(new WasmGetLocal(resultVar));
}); });
return function; return function;
} }

View File

@ -92,7 +92,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
} else { } else {
var expected = classGenerator.getClassInfo(type).pointer; var expected = classGenerator.getClassInfo(type).pointer;
var condition = new WasmReferencesEqual(new WasmGetLocal(subtypeVar), new WasmGetGlobal(expected)); var condition = new WasmReferencesEqual(new WasmGetLocal(subtypeVar), new WasmGetGlobal(expected));
function.getBody().add(new WasmReturn(condition)); function.getBody().add(condition);
} }
return function; return function;
@ -102,7 +102,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
var body = function.getBody(); var body = function.getBody();
var ranges = tagRegistry.getRanges(className); var ranges = tagRegistry.getRanges(className);
if (ranges.isEmpty()) { if (ranges.isEmpty()) {
body.add(new WasmReturn(new WasmInt32Constant(0))); body.add(new WasmInt32Constant(0));
return; return;
} }
@ -147,7 +147,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
testLower.getThenBlock().getBody().add(testUpper); testLower.getThenBlock().getBody().add(testUpper);
} }
body.add(new WasmReturn(new WasmInt32Constant(1))); body.add(new WasmInt32Constant(1));
} }
private void generateIsArray(WasmLocal subtypeVar, ValueType itemType, List<WasmExpression> body) { private void generateIsArray(WasmLocal subtypeVar, ValueType itemType, List<WasmExpression> body) {
@ -164,7 +164,7 @@ public class WasmGCSupertypeFunctionGenerator implements WasmGCSupertypeFunction
delegateToItem.getArguments().add(new WasmGetLocal(subtypeVar)); delegateToItem.getArguments().add(new WasmGetLocal(subtypeVar));
itemTest.getElseBlock().getBody().add(delegateToItem); itemTest.getElseBlock().getBody().add(delegateToItem);
body.add(new WasmReturn(itemTest)); body.add(itemTest);
} }
public WasmFunctionType getFunctionType() { public WasmFunctionType getFunctionType() {

View File

@ -395,7 +395,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
@Override @Override
public void visit(NewArrayExpr expr) { public void visit(NewArrayExpr expr) {
accept(expr.getLength(), WasmType.INT32); accept(expr.getLength(), WasmType.INT32);
var function = context.classInfoProvider().getArrayConstructor(ValueType.arrayOf(expr.getType())); var function = context.classInfoProvider().getArrayConstructor(expr.getType(), 1);
var call = new WasmCall(function, result); var call = new WasmCall(function, result);
call.setLocation(expr.getLocation()); call.setLocation(expr.getLocation());
result = call; result = call;
@ -408,9 +408,17 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
} }
@Override @Override
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType itemType, protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
Supplier<List<WasmExpression>> dimensions, TextLocation location) { Supplier<List<WasmExpression>> dimensions, TextLocation location) {
return null; var dimensionsValue = dimensions.get();
var itemType = arrayType;
for (var i = 0; i < dimensionsValue.size(); ++i) {
itemType = ((ValueType.Array) itemType).getItemType();
}
var function = context.classInfoProvider().getArrayConstructor(itemType, dimensionsValue.size());
var call = new WasmCall(function, dimensionsValue.toArray(new WasmExpression[0]));
call.setLocation(location);
return call;
} }
@Override @Override

View File

@ -45,7 +45,6 @@ import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmTag; import org.teavm.backend.wasm.model.WasmTag;
import org.teavm.backend.wasm.model.WasmType; import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmFunctionReference; import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmSetGlobal; import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.interop.Import; import org.teavm.interop.Import;
@ -342,7 +341,6 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
public WasmFunction getDummyInitializer() { public WasmFunction getDummyInitializer() {
if (dummyInitializer == null) { if (dummyInitializer == null) {
dummyInitializer = new WasmFunction(functionTypes.of(null)); dummyInitializer = new WasmFunction(functionTypes.of(null));
dummyInitializer.getBody().add(new WasmReturn());
dummyInitializer.setName(names.topLevel("teavm@dummyInitializer")); dummyInitializer.setName(names.topLevel("teavm@dummyInitializer"));
dummyInitializer.setReferenced(true); dummyInitializer.setReferenced(true);
module.functions.add(dummyInitializer); module.functions.add(dummyInitializer);

View File

@ -20,7 +20,6 @@ import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmType; import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmCallReference; import org.teavm.backend.wasm.model.expression.WasmCallReference;
import org.teavm.backend.wasm.model.expression.WasmGetLocal; import org.teavm.backend.wasm.model.expression.WasmGetLocal;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmStructGet; import org.teavm.backend.wasm.model.expression.WasmStructGet;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -40,6 +39,6 @@ public class ArrayGenerator implements WasmGCCustomGenerator {
); );
var result = new WasmCallReference(constructorRef, functionType); var result = new WasmCallReference(constructorRef, functionType);
result.getArguments().add(new WasmGetLocal(sizeLocal)); result.getArguments().add(new WasmGetLocal(sizeLocal));
function.getBody().add(new WasmReturn(result)); function.getBody().add(result);
} }
} }

View File

@ -23,7 +23,6 @@ import org.teavm.backend.wasm.model.expression.WasmCallReference;
import org.teavm.backend.wasm.model.expression.WasmConditional; import org.teavm.backend.wasm.model.expression.WasmConditional;
import org.teavm.backend.wasm.model.expression.WasmGetLocal; import org.teavm.backend.wasm.model.expression.WasmGetLocal;
import org.teavm.backend.wasm.model.expression.WasmIsNull; import org.teavm.backend.wasm.model.expression.WasmIsNull;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmStructGet; import org.teavm.backend.wasm.model.expression.WasmStructGet;
import org.teavm.backend.wasm.model.expression.WasmThrow; import org.teavm.backend.wasm.model.expression.WasmThrow;
import org.teavm.backend.wasm.runtime.WasmGCSupport; import org.teavm.backend.wasm.runtime.WasmGCSupport;
@ -62,6 +61,6 @@ public class ClassGenerators implements WasmGCCustomGenerator {
context.functionTypes().of(WasmType.INT32, classCls.getType())); context.functionTypes().of(WasmType.INT32, classCls.getType()));
call.getArguments().add(new WasmGetLocal(otherClassVar)); call.getArguments().add(new WasmGetLocal(otherClassVar));
function.getBody().add(new WasmReturn(call)); function.getBody().add(call);
} }
} }

View File

@ -27,7 +27,6 @@ import org.teavm.backend.wasm.model.expression.WasmIntBinary;
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation; import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
import org.teavm.backend.wasm.model.expression.WasmIntType; import org.teavm.backend.wasm.model.expression.WasmIntType;
import org.teavm.backend.wasm.model.expression.WasmLoadInt32; import org.teavm.backend.wasm.model.expression.WasmLoadInt32;
import org.teavm.backend.wasm.model.expression.WasmReturn;
import org.teavm.backend.wasm.model.expression.WasmSetGlobal; import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
import org.teavm.backend.wasm.model.expression.WasmSetLocal; import org.teavm.backend.wasm.model.expression.WasmSetLocal;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -48,6 +47,6 @@ public class WasmGCStringPoolGenerator implements WasmGCCustomGenerator {
var increment = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, var increment = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
new WasmGetGlobal(pointer), new WasmInt32Constant(1)); new WasmGetGlobal(pointer), new WasmInt32Constant(1));
function.getBody().add(new WasmSetGlobal(pointer, increment)); function.getBody().add(new WasmSetGlobal(pointer, increment));
function.getBody().add(new WasmReturn(new WasmGetLocal(resultLocal))); function.getBody().add(new WasmGetLocal(resultLocal));
} }
} }

View File

@ -358,9 +358,6 @@ public abstract class BaseTypeInference<T> {
@Override @Override
public void visit(ConstructMultiArrayInstruction insn) { public void visit(ConstructMultiArrayInstruction insn) {
var type = insn.getItemType(); var type = insn.getItemType();
for (var i = 0; i < insn.getDimensions().size(); ++i) {
type = ValueType.arrayOf(type);
}
type(insn.getReceiver(), type); type(insn.getReceiver(), type);
} }