mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: generate array constructor using ref.struct_new
This commit is contained in:
parent
4d416af7dc
commit
054d4c2a24
|
@ -18,7 +18,6 @@ package org.teavm.classlib.impl;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
||||||
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
|
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
|
||||||
|
@ -129,17 +128,14 @@ public class ServiceLoaderWasmGCSupport implements WasmGCCustomGeneratorFactory
|
||||||
function.setName(context.names().topLevel(context.names().suggestForClass(interfaceName) + "@services"));
|
function.setName(context.names().topLevel(context.names().suggestForClass(interfaceName) + "@services"));
|
||||||
function.setReferenced(true);
|
function.setReferenced(true);
|
||||||
context.module().functions.add(function);
|
context.module().functions.add(function);
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var util = new WasmGCGenerationUtil(context.classInfoProvider());
|
||||||
var util = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
|
function.getBody().add(util.allocateArrayWithElements(ValueType.parse(Object.class), () -> {
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(context.typeMapper().mapType(ValueType.parse(Object[].class)));
|
|
||||||
util.allocateArrayWithElements(ValueType.parse(Object.class), () -> {
|
|
||||||
var items = new ArrayList<WasmExpression>();
|
var items = new ArrayList<WasmExpression>();
|
||||||
for (var implementationName : implementations) {
|
for (var implementationName : implementations) {
|
||||||
items.add(instantiateService(context, function, implementationName));
|
items.add(instantiateService(context, function, implementationName));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}, null, null, function.getBody());
|
}));
|
||||||
|
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,14 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import org.teavm.ast.ArrayFromDataExpr;
|
||||||
import org.teavm.ast.ArrayType;
|
import org.teavm.ast.ArrayType;
|
||||||
import org.teavm.ast.CastExpr;
|
import org.teavm.ast.CastExpr;
|
||||||
import org.teavm.ast.Expr;
|
import org.teavm.ast.Expr;
|
||||||
import org.teavm.ast.InstanceOfExpr;
|
import org.teavm.ast.InstanceOfExpr;
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.ast.InvocationType;
|
import org.teavm.ast.InvocationType;
|
||||||
|
import org.teavm.ast.NewArrayExpr;
|
||||||
import org.teavm.ast.QualificationExpr;
|
import org.teavm.ast.QualificationExpr;
|
||||||
import org.teavm.ast.Statement;
|
import org.teavm.ast.Statement;
|
||||||
import org.teavm.ast.SubscriptExpr;
|
import org.teavm.ast.SubscriptExpr;
|
||||||
|
@ -767,7 +769,26 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
public void visit(NewArrayExpr expr) {
|
||||||
|
var block = new WasmBlock(false);
|
||||||
|
block.setType(mapType(ValueType.arrayOf(expr.getType())));
|
||||||
|
|
||||||
|
var callSiteId = generateCallSiteId(expr.getLocation());
|
||||||
|
callSiteId.generateRegister(block.getBody(), expr.getLocation());
|
||||||
|
|
||||||
|
allocateArray(expr.getType(), () -> {
|
||||||
|
accept(expr.getLength());
|
||||||
|
return result;
|
||||||
|
}, expr.getLocation(), null, block.getBody());
|
||||||
|
|
||||||
|
if (block.getBody().size() == 1) {
|
||||||
|
result = block.getBody().get(0);
|
||||||
|
} else {
|
||||||
|
result = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
||||||
WasmLocal local, List<WasmExpression> target) {
|
WasmLocal local, List<WasmExpression> target) {
|
||||||
int classPointer = classGenerator.getClassPointer(ValueType.arrayOf(itemType));
|
int classPointer = classGenerator.getClassPointer(ValueType.arrayOf(itemType));
|
||||||
var allocFunction = context.functions().forStaticMethod(new MethodReference(Allocator.class, "allocateArray",
|
var allocFunction = context.functions().forStaticMethod(new MethodReference(Allocator.class, "allocateArray",
|
||||||
|
@ -783,6 +804,61 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayFromDataExpr expr) {
|
||||||
|
var type = expr.getType();
|
||||||
|
|
||||||
|
var arrayType = ArrayType.OBJECT;
|
||||||
|
if (type instanceof ValueType.Primitive) {
|
||||||
|
switch (((ValueType.Primitive) type).getKind()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
case BYTE:
|
||||||
|
arrayType = ArrayType.BYTE;
|
||||||
|
break;
|
||||||
|
case SHORT:
|
||||||
|
arrayType = ArrayType.SHORT;
|
||||||
|
break;
|
||||||
|
case CHARACTER:
|
||||||
|
arrayType = ArrayType.CHAR;
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
arrayType = ArrayType.INT;
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
arrayType = ArrayType.LONG;
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
arrayType = ArrayType.FLOAT;
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
arrayType = ArrayType.DOUBLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var wasmArrayType = mapType(ValueType.arrayOf(expr.getType()));
|
||||||
|
var block = new WasmBlock(false);
|
||||||
|
block.setType(wasmArrayType);
|
||||||
|
var callSiteId = generateCallSiteId(expr.getLocation());
|
||||||
|
callSiteId.generateRegister(block.getBody(), expr.getLocation());
|
||||||
|
|
||||||
|
var array = tempVars.acquire(wasmArrayType);
|
||||||
|
allocateArray(expr.getType(), () -> new WasmInt32Constant(expr.getData().size()), expr.getLocation(), array,
|
||||||
|
block.getBody());
|
||||||
|
|
||||||
|
for (int i = 0; i < expr.getData().size(); ++i) {
|
||||||
|
var arrayData = unwrapArray(new WasmGetLocal(array));
|
||||||
|
block.getBody().add(storeArrayItem(arrayData, new WasmInt32Constant(i), expr.getData().get(i),
|
||||||
|
arrayType));
|
||||||
|
}
|
||||||
|
|
||||||
|
block.getBody().add(new WasmGetLocal(array));
|
||||||
|
block.setLocation(expr.getLocation());
|
||||||
|
tempVars.release(array);
|
||||||
|
|
||||||
|
result = block;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
||||||
Supplier<List<WasmExpression>> dimensions, TextLocation location) {
|
Supplier<List<WasmExpression>> dimensions, TextLocation location) {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import org.teavm.ast.ArrayFromDataExpr;
|
|
||||||
import org.teavm.ast.ArrayType;
|
import org.teavm.ast.ArrayType;
|
||||||
import org.teavm.ast.AssignmentStatement;
|
import org.teavm.ast.AssignmentStatement;
|
||||||
import org.teavm.ast.BinaryExpr;
|
import org.teavm.ast.BinaryExpr;
|
||||||
|
@ -46,7 +45,6 @@ import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.ast.InvocationType;
|
import org.teavm.ast.InvocationType;
|
||||||
import org.teavm.ast.MonitorEnterStatement;
|
import org.teavm.ast.MonitorEnterStatement;
|
||||||
import org.teavm.ast.MonitorExitStatement;
|
import org.teavm.ast.MonitorExitStatement;
|
||||||
import org.teavm.ast.NewArrayExpr;
|
|
||||||
import org.teavm.ast.NewExpr;
|
import org.teavm.ast.NewExpr;
|
||||||
import org.teavm.ast.NewMultiArrayExpr;
|
import org.teavm.ast.NewMultiArrayExpr;
|
||||||
import org.teavm.ast.OperationType;
|
import org.teavm.ast.OperationType;
|
||||||
|
@ -1018,87 +1016,9 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
protected abstract void allocateObject(String className, TextLocation location, WasmLocal local,
|
protected abstract void allocateObject(String className, TextLocation location, WasmLocal local,
|
||||||
List<WasmExpression> target);
|
List<WasmExpression> target);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(NewArrayExpr expr) {
|
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(mapType(ValueType.arrayOf(expr.getType())));
|
|
||||||
|
|
||||||
var callSiteId = generateCallSiteId(expr.getLocation());
|
|
||||||
callSiteId.generateRegister(block.getBody(), expr.getLocation());
|
|
||||||
|
|
||||||
allocateArray(expr.getType(), () -> {
|
|
||||||
accept(expr.getLength());
|
|
||||||
return result;
|
|
||||||
}, expr.getLocation(), null, block.getBody());
|
|
||||||
|
|
||||||
if (block.getBody().size() == 1) {
|
|
||||||
result = block.getBody().get(0);
|
|
||||||
} else {
|
|
||||||
result = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
|
||||||
WasmLocal local, List<WasmExpression> target);
|
|
||||||
|
|
||||||
protected abstract WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
protected abstract WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
||||||
Supplier<List<WasmExpression>> dimensions, TextLocation location);
|
Supplier<List<WasmExpression>> dimensions, TextLocation location);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ArrayFromDataExpr expr) {
|
|
||||||
var type = expr.getType();
|
|
||||||
|
|
||||||
var arrayType = ArrayType.OBJECT;
|
|
||||||
if (type instanceof ValueType.Primitive) {
|
|
||||||
switch (((ValueType.Primitive) type).getKind()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
case BYTE:
|
|
||||||
arrayType = ArrayType.BYTE;
|
|
||||||
break;
|
|
||||||
case SHORT:
|
|
||||||
arrayType = ArrayType.SHORT;
|
|
||||||
break;
|
|
||||||
case CHARACTER:
|
|
||||||
arrayType = ArrayType.CHAR;
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
arrayType = ArrayType.INT;
|
|
||||||
break;
|
|
||||||
case LONG:
|
|
||||||
arrayType = ArrayType.LONG;
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
arrayType = ArrayType.FLOAT;
|
|
||||||
break;
|
|
||||||
case DOUBLE:
|
|
||||||
arrayType = ArrayType.DOUBLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var wasmArrayType = mapType(ValueType.arrayOf(expr.getType()));
|
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(wasmArrayType);
|
|
||||||
var callSiteId = generateCallSiteId(expr.getLocation());
|
|
||||||
callSiteId.generateRegister(block.getBody(), expr.getLocation());
|
|
||||||
|
|
||||||
var array = tempVars.acquire(wasmArrayType);
|
|
||||||
allocateArray(expr.getType(), () -> new WasmInt32Constant(expr.getData().size()), expr.getLocation(), array,
|
|
||||||
block.getBody());
|
|
||||||
|
|
||||||
for (int i = 0; i < expr.getData().size(); ++i) {
|
|
||||||
var arrayData = unwrapArray(new WasmGetLocal(array));
|
|
||||||
block.getBody().add(storeArrayItem(arrayData, new WasmInt32Constant(i), expr.getData().get(i),
|
|
||||||
arrayType));
|
|
||||||
}
|
|
||||||
|
|
||||||
block.getBody().add(new WasmGetLocal(array));
|
|
||||||
block.setLocation(expr.getLocation());
|
|
||||||
tempVars.release(array);
|
|
||||||
|
|
||||||
result = block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewMultiArrayExpr expr) {
|
public void visit(NewMultiArrayExpr expr) {
|
||||||
var block = new WasmBlock(false);
|
var block = new WasmBlock(false);
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableEntry;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableEntry;
|
||||||
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
import org.teavm.backend.wasm.generate.gc.WasmGCInitializerContributor;
|
||||||
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;
|
||||||
|
@ -52,7 +51,6 @@ import org.teavm.backend.wasm.model.expression.WasmArrayCopy;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
|
import org.teavm.backend.wasm.model.expression.WasmArrayGet;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
|
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
|
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCast;
|
import org.teavm.backend.wasm.model.expression.WasmCast;
|
||||||
|
@ -1543,14 +1541,8 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
functionTypes.of(null)));
|
functionTypes.of(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var util = new WasmGCGenerationUtil(this);
|
||||||
var util = new WasmGCGenerationUtil(this, tempVars);
|
function.getBody().add(util.allocateArrayWithElements(ValueType.parse(Enum.class), () -> fields));
|
||||||
var local = tempVars.acquire(enumArrayStruct.getReference());
|
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(enumArrayStruct.getReference());
|
|
||||||
util.allocateArrayWithElements(ValueType.parse(Enum.class), () -> fields, null, null, block.getBody());
|
|
||||||
function.getBody().add(block);
|
|
||||||
tempVars.release(local);
|
|
||||||
|
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ 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.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.WasmArray;
|
||||||
|
@ -75,12 +74,10 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
queue.add(() -> {
|
queue.add(() -> {
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
||||||
function.add(sizeLocal);
|
function.add(sizeLocal);
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var genUtil = new WasmGCGenerationUtil(classInfoProvider);
|
||||||
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
|
||||||
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());
|
function.getBody().add(genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal)));
|
||||||
function.getBody().add(new WasmGetLocal(targetVar));
|
|
||||||
});
|
});
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,8 @@ public class WasmGCTypeMapper {
|
||||||
if (type instanceof ValueType.Object) {
|
if (type instanceof ValueType.Object) {
|
||||||
var className = ((ValueType.Object) type).getClassName();
|
var className = ((ValueType.Object) type).getClassName();
|
||||||
var cls = classes.get(className);
|
var cls = classes.get(className);
|
||||||
if (cls != null) {
|
if (cls == null) {
|
||||||
className = "java.lang.Object";
|
type = ValueType.object("java.lang.Object");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (degree-- > 0) {
|
while (degree-- > 0) {
|
||||||
|
|
|
@ -18,83 +18,49 @@ package org.teavm.backend.wasm.generate.gc.methods;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
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.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.model.WasmArray;
|
import org.teavm.backend.wasm.model.WasmArray;
|
||||||
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.WasmArrayNewDefault;
|
import org.teavm.backend.wasm.model.expression.WasmArrayNewDefault;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArrayNewFixed;
|
import org.teavm.backend.wasm.model.expression.WasmArrayNewFixed;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
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.WasmNullConstant;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
|
import org.teavm.backend.wasm.model.expression.WasmStructNew;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmStructNewDefault;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmStructSet;
|
|
||||||
import org.teavm.model.TextLocation;
|
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
public class WasmGCGenerationUtil {
|
public class WasmGCGenerationUtil {
|
||||||
private WasmGCClassInfoProvider classInfoProvider;
|
private WasmGCClassInfoProvider classInfoProvider;
|
||||||
private TemporaryVariablePool tempVars;
|
|
||||||
|
|
||||||
public WasmGCGenerationUtil(WasmGCClassInfoProvider classInfoProvider, TemporaryVariablePool tempVars) {
|
public WasmGCGenerationUtil(WasmGCClassInfoProvider classInfoProvider) {
|
||||||
this.classInfoProvider = classInfoProvider;
|
this.classInfoProvider = classInfoProvider;
|
||||||
this.tempVars = tempVars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
public WasmExpression allocateArray(ValueType itemType, Supplier<WasmExpression> length) {
|
||||||
WasmLocal local, List<WasmExpression> target) {
|
return allocateArray(itemType, arrayType -> new WasmArrayNewDefault(arrayType, length.get()));
|
||||||
allocateArray(itemType, location, local, target, arrayType -> new WasmArrayNewDefault(arrayType, length.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void allocateArrayWithElements(ValueType itemType, Supplier<List<? extends WasmExpression>> data,
|
public WasmExpression allocateArrayWithElements(ValueType itemType,
|
||||||
TextLocation location, WasmLocal local, List<WasmExpression> target) {
|
Supplier<List<? extends WasmExpression>> data) {
|
||||||
allocateArray(itemType, location, local, target, arrayType -> {
|
return allocateArray(itemType, arrayType -> {
|
||||||
var expr = new WasmArrayNewFixed(arrayType);
|
var expr = new WasmArrayNewFixed(arrayType);
|
||||||
expr.getElements().addAll(data.get());
|
expr.getElements().addAll(data.get());
|
||||||
return expr;
|
return expr;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void allocateArray(ValueType itemType, TextLocation location,
|
public WasmExpression allocateArray(ValueType itemType, Function<WasmArray, WasmExpression> data) {
|
||||||
WasmLocal local, List<WasmExpression> target, Function<WasmArray, WasmExpression> data) {
|
|
||||||
var classInfo = classInfoProvider.getClassInfo(ValueType.arrayOf(itemType));
|
var classInfo = classInfoProvider.getClassInfo(ValueType.arrayOf(itemType));
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(classInfo.getType());
|
|
||||||
var targetVar = local;
|
|
||||||
if (targetVar == null) {
|
|
||||||
targetVar = tempVars.acquire(classInfo.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
var structNew = new WasmSetLocal(targetVar, new WasmStructNewDefault(classInfo.getStructure()));
|
|
||||||
structNew.setLocation(location);
|
|
||||||
target.add(structNew);
|
|
||||||
|
|
||||||
var initClassField = new WasmStructSet(classInfo.getStructure(), new WasmGetLocal(targetVar),
|
|
||||||
WasmGCClassInfoProvider.CLASS_FIELD_OFFSET, new WasmGetGlobal(classInfo.getPointer()));
|
|
||||||
initClassField.setLocation(location);
|
|
||||||
target.add(initClassField);
|
|
||||||
|
|
||||||
var wasmArrayType = (WasmType.CompositeReference) classInfo.getStructure().getFields()
|
var wasmArrayType = (WasmType.CompositeReference) classInfo.getStructure().getFields()
|
||||||
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET)
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET)
|
||||||
.getUnpackedType();
|
.getUnpackedType();
|
||||||
var wasmArray = (WasmArray) wasmArrayType.composite;
|
var wasmArray = (WasmArray) wasmArrayType.composite;
|
||||||
var initArrayField = new WasmStructSet(
|
|
||||||
classInfo.getStructure(),
|
|
||||||
new WasmGetLocal(targetVar),
|
|
||||||
WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET,
|
|
||||||
data.apply(wasmArray)
|
|
||||||
);
|
|
||||||
initArrayField.setLocation(location);
|
|
||||||
target.add(initArrayField);
|
|
||||||
|
|
||||||
if (local == null) {
|
var structNew = new WasmStructNew(classInfo.getStructure());
|
||||||
var getLocal = new WasmGetLocal(targetVar);
|
structNew.getInitializers().add(new WasmGetGlobal(classInfo.getPointer()));
|
||||||
getLocal.setLocation(location);
|
structNew.getInitializers().add(new WasmNullConstant(WasmType.Reference.EQ));
|
||||||
target.add(getLocal);
|
structNew.getInitializers().add(data.apply(wasmArray));
|
||||||
tempVars.release(targetVar);
|
return structNew;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
WasmFunction function, int firstVariable, boolean async, PreciseTypeInference types) {
|
WasmFunction function, int firstVariable, boolean async, PreciseTypeInference types) {
|
||||||
super(context, currentMethod, function, firstVariable, async);
|
super(context, currentMethod, function, firstVariable, async);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
generationUtil = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
|
generationUtil = new WasmGCGenerationUtil(context.classInfoProvider());
|
||||||
this.types = types;
|
this.types = types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,28 +370,22 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArrayFromDataExpr expr) {
|
public void visit(ArrayFromDataExpr expr) {
|
||||||
var wasmArrayType = (WasmType.CompositeReference) mapType(ValueType.arrayOf(expr.getType()));
|
var wasmArrayType = (WasmType.CompositeReference) mapType(ValueType.arrayOf(expr.getType()));
|
||||||
var block = new WasmBlock(false);
|
|
||||||
block.setType(wasmArrayType);
|
|
||||||
var wasmArrayStruct = (WasmStructure) wasmArrayType.composite;
|
var wasmArrayStruct = (WasmStructure) wasmArrayType.composite;
|
||||||
var wasmArrayDataType = (WasmType.CompositeReference) wasmArrayStruct.getFields()
|
var wasmArrayDataType = (WasmType.CompositeReference) wasmArrayStruct.getFields()
|
||||||
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
var wasmArray = (WasmArray) wasmArrayDataType.composite;
|
var wasmArray = (WasmArray) wasmArrayDataType.composite;
|
||||||
var array = tempVars.acquire(wasmArrayType);
|
|
||||||
|
|
||||||
generationUtil.allocateArrayWithElements(expr.getType(), () -> {
|
var array = generationUtil.allocateArrayWithElements(expr.getType(), () -> {
|
||||||
var items = new ArrayList<WasmExpression>();
|
var items = new ArrayList<WasmExpression>();
|
||||||
for (int i = 0; i < expr.getData().size(); ++i) {
|
for (int i = 0; i < expr.getData().size(); ++i) {
|
||||||
accept(expr.getData().get(i), wasmArray.getElementType().asUnpackedType());
|
accept(expr.getData().get(i), wasmArray.getElementType().asUnpackedType());
|
||||||
items.add(result);
|
items.add(result);
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}, expr.getLocation(), array, block.getBody());
|
});
|
||||||
|
array.setLocation(expr.getLocation());
|
||||||
|
|
||||||
block.getBody().add(new WasmGetLocal(array));
|
result = array;
|
||||||
block.setLocation(expr.getLocation());
|
|
||||||
tempVars.release(array);
|
|
||||||
|
|
||||||
result = block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -403,12 +397,6 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
result = call;
|
result = call;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
|
||||||
WasmLocal local, List<WasmExpression> target) {
|
|
||||||
generationUtil.allocateArray(itemType, length, location, local, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
protected WasmExpression allocateMultiArray(List<WasmExpression> target, ValueType arrayType,
|
||||||
Supplier<List<WasmExpression>> dimensions, TextLocation location) {
|
Supplier<List<WasmExpression>> dimensions, TextLocation location) {
|
||||||
|
|
|
@ -23,18 +23,15 @@ import java.util.Arrays;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
|
||||||
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
import org.teavm.backend.wasm.generate.gc.methods.WasmGCGenerationUtil;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
|
||||||
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
||||||
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.WasmCall;
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
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.WasmInt32Constant;
|
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
@ -105,13 +102,11 @@ public class WasmGCResourcesGenerator implements WasmGCCustomGenerator {
|
||||||
WasmType.INT32, new WasmInt32Constant(0));
|
WasmType.INT32, new WasmInt32Constant(0));
|
||||||
context.module().globals.add(baseGlobal);
|
context.module().globals.add(baseGlobal);
|
||||||
|
|
||||||
var genUtil = new WasmGCGenerationUtil(context.classInfoProvider(), new TemporaryVariablePool(function));
|
var genUtil = new WasmGCGenerationUtil(context.classInfoProvider());
|
||||||
var local = new WasmLocal(context.typeMapper().mapType(ValueType.parse(WasmGCResources.Resource[].class)));
|
|
||||||
function.add(local);
|
|
||||||
var constructor = context.functions().forStaticMethod(new MethodReference(WasmGCResources.class,
|
var constructor = context.functions().forStaticMethod(new MethodReference(WasmGCResources.class,
|
||||||
"create", String.class, int.class, int.class, WasmGCResources.Resource.class));
|
"create", String.class, int.class, int.class, WasmGCResources.Resource.class));
|
||||||
|
|
||||||
genUtil.allocateArrayWithElements(
|
function.getBody().add(genUtil.allocateArrayWithElements(
|
||||||
ValueType.parse(WasmGCResources.Resource.class),
|
ValueType.parse(WasmGCResources.Resource.class),
|
||||||
() -> {
|
() -> {
|
||||||
var items = new ArrayList<WasmExpression>();
|
var items = new ArrayList<WasmExpression>();
|
||||||
|
@ -123,12 +118,8 @@ public class WasmGCResourcesGenerator implements WasmGCCustomGenerator {
|
||||||
items.add(new WasmCall(constructor, new WasmGetGlobal(name.global), offset, end));
|
items.add(new WasmCall(constructor, new WasmGetGlobal(name.global), offset, end));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
},
|
}
|
||||||
null,
|
));
|
||||||
local,
|
|
||||||
function.getBody()
|
|
||||||
);
|
|
||||||
function.getBody().add(new WasmGetLocal(local));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user