diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java index 1ff61f29e..18bb5b131 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java @@ -19,6 +19,7 @@ import static org.teavm.model.lowlevel.ExceptionHandlingUtil.isManagedMethodCall import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import org.teavm.ast.ArrayType; import org.teavm.ast.CastExpr; import org.teavm.ast.Expr; @@ -782,14 +783,14 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor { } @Override - protected void allocateArray(ValueType itemType, WasmExpression length, TextLocation location, WasmLocal local, - List target) { + protected void allocateArray(ValueType itemType, Supplier length, TextLocation location, + WasmLocal local, List target) { int classPointer = classGenerator.getClassPointer(ValueType.arrayOf(itemType)); var allocFunction = context.functions().forStaticMethod(new MethodReference(Allocator.class, "allocateArray", RuntimeClass.class, int.class, Address.class)); var call = new WasmCall(allocFunction); call.getArguments().add(new WasmInt32Constant(classPointer)); - call.getArguments().add(length); + call.getArguments().add(length.get()); call.setLocation(location); if (local != null) { target.add(new WasmSetLocal(local, call)); @@ -800,9 +801,10 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor { @Override protected WasmExpression allocateMultiArray(List target, ValueType itemType, - List dimensions, TextLocation location) { + Supplier> dimensions, TextLocation location) { int dimensionList = -1; - for (var dimension : dimensions) { + var dimensionsValue = dimensions.get(); + for (var dimension : dimensionsValue) { int dimensionAddress = binaryWriter.append(DataPrimitives.INT.createValue()); if (dimensionList < 0) { dimensionList = dimensionAddress; @@ -817,7 +819,7 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor { var call = new WasmCall(allocFunction); call.getArguments().add(new WasmInt32Constant(classPointer)); call.getArguments().add(new WasmInt32Constant(dimensionList)); - call.getArguments().add(new WasmInt32Constant(dimensions.size())); + call.getArguments().add(new WasmInt32Constant(dimensionsValue.size())); call.setLocation(location); return call; } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java index 7a4987ff4..f980b1b5a 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import org.teavm.ast.ArrayFromDataExpr; import org.teavm.ast.ArrayType; import org.teavm.ast.AssignmentStatement; @@ -1025,9 +1026,10 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp var callSiteId = generateCallSiteId(expr.getLocation()); callSiteId.generateRegister(block.getBody(), expr.getLocation()); - accept(expr.getLength()); - var length = result; - allocateArray(expr.getType(), length, expr.getLocation(), null, block.getBody()); + allocateArray(expr.getType(), () -> { + accept(expr.getLength()); + return result; + }, expr.getLocation(), null, block.getBody()); if (block.getBody().size() == 1) { result = block.getBody().get(0); @@ -1036,11 +1038,11 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp } } - protected abstract void allocateArray(ValueType itemType, WasmExpression length, TextLocation location, + protected abstract void allocateArray(ValueType itemType, Supplier length, TextLocation location, WasmLocal local, List target); protected abstract WasmExpression allocateMultiArray(List target, ValueType itemType, - List dimensions, TextLocation location); + Supplier> dimensions, TextLocation location); @Override public void visit(ArrayFromDataExpr expr) { @@ -1081,7 +1083,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp callSiteId.generateRegister(block.getBody(), expr.getLocation()); var array = tempVars.acquire(wasmArrayType); - allocateArray(expr.getType(), new WasmInt32Constant(expr.getData().size()), expr.getLocation(), array, + allocateArray(expr.getType(), () -> new WasmInt32Constant(expr.getData().size()), expr.getLocation(), array, block.getBody()); for (int i = 0; i < expr.getData().size(); ++i) { @@ -1104,15 +1106,19 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp var callSiteId = generateCallSiteId(expr.getLocation()); callSiteId.generateRegister(block.getBody(), expr.getLocation()); - var wasmDimensions = new ArrayList(); var arrayType = expr.getType(); for (var dimension : expr.getDimensions()) { - accept(dimension); - wasmDimensions.add(result); arrayType = ValueType.arrayOf(arrayType); } block.setType(mapType(arrayType)); - var call = allocateMultiArray(block.getBody(), expr.getType(), wasmDimensions, expr.getLocation()); + var call = allocateMultiArray(block.getBody(), expr.getType(), () -> { + var wasmDimensions = new ArrayList(); + for (var dimension : expr.getDimensions()) { + accept(dimension); + wasmDimensions.add(result); + } + return wasmDimensions; + }, expr.getLocation()); block.getBody().add(call); if (block.getBody().size() == 1) { diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java index 2e9864994..a1aefe176 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java @@ -1303,7 +1303,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit var local = tempVars.acquire(enumArrayStruct.getReference()); var block = new WasmBlock(false); block.setType(enumArrayStruct.getReference()); - util.allocateArray(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)); tempVars.release(local); diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCNewArrayFunctionGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCNewArrayFunctionGenerator.java index d47cbee5c..d3496fd7e 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCNewArrayFunctionGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCNewArrayFunctionGenerator.java @@ -54,7 +54,7 @@ class WasmGCNewArrayFunctionGenerator { var targetVar = new WasmLocal(classInfoProvider.getClassInfo(ValueType.arrayOf(itemType)).getType(), "result"); 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))); return function; } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationUtil.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationUtil.java index daa3af067..de49d62ba 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationUtil.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationUtil.java @@ -17,6 +17,7 @@ package org.teavm.backend.wasm.generate.gc.methods; import java.util.List; import java.util.function.Function; +import java.util.function.Supplier; import org.teavm.backend.wasm.generate.TemporaryVariablePool; import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider; import org.teavm.backend.wasm.model.WasmArray; @@ -43,16 +44,16 @@ public class WasmGCGenerationUtil { this.tempVars = tempVars; } - public void allocateArray(ValueType itemType, WasmExpression length, TextLocation location, WasmLocal local, - List target) { - allocateArray(itemType, location, local, target, arrayType -> new WasmArrayNewDefault(arrayType, length)); + public void allocateArray(ValueType itemType, Supplier length, TextLocation location, + WasmLocal local, List target) { + allocateArray(itemType, location, local, target, arrayType -> new WasmArrayNewDefault(arrayType, length.get())); } - public void allocateArray(ValueType itemType, List data, TextLocation location, - WasmLocal local, List target) { + public void allocateArrayWithElements(ValueType itemType, Supplier> data, + TextLocation location, WasmLocal local, List target) { allocateArray(itemType, location, local, target, arrayType -> { var expr = new WasmArrayNewFixed(arrayType); - expr.getElements().addAll(data); + expr.getElements().addAll(data.get()); return expr; }); } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java index ecde44c9d..460a076e7 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java @@ -16,6 +16,7 @@ package org.teavm.backend.wasm.generate.gc.methods; import java.util.List; +import java.util.function.Supplier; import org.teavm.ast.ArrayType; import org.teavm.ast.BinaryExpr; import org.teavm.ast.ConditionalExpr; @@ -332,14 +333,14 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor { } @Override - protected void allocateArray(ValueType itemType, WasmExpression length, TextLocation location, WasmLocal local, - List target) { + protected void allocateArray(ValueType itemType, Supplier length, TextLocation location, + WasmLocal local, List target) { generationUtil.allocateArray(itemType, length, location, local, target); } @Override protected WasmExpression allocateMultiArray(List target, ValueType itemType, - List dimensions, TextLocation location) { + Supplier> dimensions, TextLocation location) { return null; }