wasm: move common part of wasm expression generator in order to later reuse it with Wasm GC BE

This commit is contained in:
Alexey Andreev 2024-07-09 20:49:57 +02:00
parent 13a959ce67
commit 172de8e737
13 changed files with 1846 additions and 1523 deletions

View File

@ -554,7 +554,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
generateMethods(classes, context, generator, classGenerator, binaryWriter, module, dwarfClassGen);
new WasmInteropFunctionGenerator(classGenerator, functionTypes).generateFunctions(module);
exceptionHandlingIntrinsic.postProcess(context.callSites);
exceptionHandlingIntrinsic.postProcess(context.callSites());
generateIsSupertypeFunctions(tagRegistry, classGenerator, functions);
classGenerator.postProcess();
new WasmSpecialFunctionGenerator(classGenerator, functionTypes, gcIntrinsic.regionSizeExpressions)
@ -821,7 +821,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
}
var methodGeneratorContext = new MethodGeneratorContextImpl(binaryWriter,
context.getStringPool(), context.getDiagnostics(), context.functions, classGenerator, classes);
context.getStringPool(), context.getDiagnostics(), context.functions(), classGenerator, classes);
for (MethodHolder method : methods) {
ClassHolder cls = classes.get(method.getOwnerName());
@ -848,7 +848,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
if (implementor.hasModifier(ElementModifier.NATIVE)) {
var methodGenerator = context.getGenerator(method.getReference());
if (methodGenerator != null) {
var function = context.functions.forMethod(method);
var function = context.functions().forMethod(method);
methodGenerator.apply(method.getReference(), function, methodGeneratorContext);
} else if (!isShadowStackMethod(method.getReference())) {
if (context.getImportedMethod(method.getReference()) == null) {
@ -866,7 +866,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
if (method == implementor) {
generator.generate(method.getReference(), implementor);
} else {
generateStub(context.functions, method, implementor);
generateStub(context.functions(), method, implementor);
}
if (dwarfClassGen != null) {
var dwarfClass = dwarfClassGen.getClass(method.getOwnerName());
@ -1203,8 +1203,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
var block = new WasmBlock(false);
block.setType(WasmType.INT32);
var callSiteId = manager.generateCallSiteId(invocation.getLocation());
block.getBody().add(manager.generateRegisterCallSite(callSiteId,
invocation.getLocation()));
callSiteId.generateRegister(block.getBody(), invocation.getLocation());
block.getBody().add(arg);
arg = block;
}

View File

@ -17,10 +17,9 @@ package org.teavm.backend.wasm.generate;
import org.teavm.backend.wasm.model.expression.WasmExpression;
abstract class CachedExpression {
abstract WasmExpression expr();
public abstract class CachedExpression {
public abstract WasmExpression expr();
void release() {
public void release() {
}
}

View File

@ -24,10 +24,10 @@ import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
import org.teavm.backend.wasm.model.expression.WasmSetLocal;
import org.teavm.model.TextLocation;
class ExpressionCache {
public class ExpressionCache {
private TemporaryVariablePool tmpVars;
ExpressionCache(TemporaryVariablePool tmpVars) {
public ExpressionCache(TemporaryVariablePool tmpVars) {
this.tmpVars = tmpVars;
}
@ -56,7 +56,7 @@ class ExpressionCache {
}
@Override
WasmExpression expr() {
public WasmExpression expr() {
return new WasmGetLocal(localVar);
}
}
@ -69,12 +69,12 @@ class ExpressionCache {
}
@Override
WasmExpression expr() {
public WasmExpression expr() {
return new WasmGetLocal(tmpVar);
}
@Override
void release() {
public void release() {
tmpVars.release(tmpVar);
}
}
@ -87,7 +87,7 @@ class ExpressionCache {
}
@Override
WasmExpression expr() {
public WasmExpression expr() {
return new WasmInt32Constant(value);
}
}

View File

@ -23,15 +23,15 @@ import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmType;
class TemporaryVariablePool {
public class TemporaryVariablePool {
private WasmFunction function;
private Map<WasmType, Deque<WasmLocal>> temporaryVariablesByType = new HashMap<>();
TemporaryVariablePool(WasmFunction function) {
public TemporaryVariablePool(WasmFunction function) {
this.function = function;
}
WasmLocal acquire(WasmType type) {
public WasmLocal acquire(WasmType type) {
var stack = temporaryVariablesByType.computeIfAbsent(type, k -> new ArrayDeque<>());
WasmLocal variable = stack.pollFirst();
if (variable == null) {
@ -41,7 +41,7 @@ class TemporaryVariablePool {
return variable;
}
void release(WasmLocal variable) {
public void release(WasmLocal variable) {
var stack = temporaryVariablesByType.get(variable.getType());
stack.push(variable);
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import org.teavm.backend.lowlevel.generate.NameProvider;
import org.teavm.backend.wasm.WasmFunctionRepository;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationContext;
import org.teavm.backend.wasm.generators.WasmMethodGenerator;
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
import org.teavm.backend.wasm.model.WasmModule;
@ -42,11 +43,11 @@ import org.teavm.model.classes.VirtualTableProvider;
import org.teavm.model.lowlevel.CallSiteDescriptor;
import org.teavm.model.lowlevel.Characteristics;
public class WasmGenerationContext {
public class WasmGenerationContext implements BaseWasmGenerationContext {
private ClassReaderSource classSource;
public final WasmModule module;
public final WasmFunctionTypes functionTypes;
public final WasmFunctionRepository functions;
private final WasmFunctionTypes functionTypes;
private final WasmFunctionRepository functions;
private Diagnostics diagnostics;
private VirtualTableProvider vtableProvider;
private TagRegistry tagRegistry;
@ -59,7 +60,7 @@ public class WasmGenerationContext {
private Map<MethodReference, IntrinsicHolder> intrinsicCache = new HashMap<>();
private Map<MethodReference, GeneratorHolder> generatorCache = new HashMap<>();
private WasmTag exceptionTag;
public final List<CallSiteDescriptor> callSites = new ArrayList<>();
private final List<CallSiteDescriptor> callSites = new ArrayList<>();
public WasmGenerationContext(ClassReaderSource classSource, WasmModule module, WasmFunctionTypes functionTypes,
WasmFunctionRepository functions, Diagnostics diagnostics, VirtualTableProvider vtableProvider,
@ -78,6 +79,25 @@ public class WasmGenerationContext {
this.exceptionTag = exceptionTag;
}
@Override
public WasmFunctionRepository functions() {
return functions;
}
@Override
public WasmFunctionTypes functionTypes() {
return functionTypes;
}
@Override
public ClassReaderSource classSource() {
return classSource;
}
public List<CallSiteDescriptor> callSites() {
return callSites;
}
public void addIntrinsic(WasmIntrinsic intrinsic) {
intrinsics.add(intrinsic);
}
@ -167,6 +187,7 @@ public class WasmGenerationContext {
return diagnostics;
}
@Override
public WasmTag getExceptionTag() {
return exceptionTag;
}

View File

@ -57,7 +57,7 @@ public class WasmGenerator {
MethodHolder method = cls.getMethod(methodReference.getDescriptor());
RegularMethodNode methodAst = decompiler.decompileRegular(bodyMethod);
WasmFunction function = context.functions.forMethod(method);
WasmFunction function = context.functions().forMethod(method);
int firstVariable = method.hasModifier(ElementModifier.STATIC) ? 1 : 0;
for (int i = firstVariable; i < methodAst.getVariables().size(); ++i) {
VariableNode variable = methodAst.getVariables().get(i);
@ -97,7 +97,7 @@ public class WasmGenerator {
}
public WasmFunction generateNative(MethodReader method) {
var function = context.functions.forMethod(method);
var function = context.functions().forMethod(method);
var importedMethod = context.getImportedMethod(method.getReference());
if (importedMethod != null) {

View File

@ -0,0 +1,31 @@
/*
* 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.generate.common.methods;
import org.teavm.backend.wasm.WasmFunctionRepository;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.model.WasmTag;
import org.teavm.model.ClassReaderSource;
public interface BaseWasmGenerationContext {
WasmFunctionRepository functions();
WasmFunctionTypes functionTypes();
WasmTag getExceptionTag();
ClassReaderSource classSource();
}

View File

@ -23,7 +23,7 @@ import java.util.Map;
import org.teavm.backend.lowlevel.generate.NameProvider;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.generate.gc.initialization.WasmGCInitializerContributor;
import org.teavm.backend.wasm.generate.gc.method.WasmGCFunctionProvider;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCFunctionProvider;
import org.teavm.backend.wasm.generate.gc.strings.WasmGCStringPool;
import org.teavm.backend.wasm.model.WasmArray;
import org.teavm.backend.wasm.model.WasmFunction;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.backend.wasm.generate.gc.method;
package org.teavm.backend.wasm.generate.gc.methods;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.model.MethodReference;

View File

@ -20,7 +20,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCStandardClasses;
import org.teavm.backend.wasm.generate.gc.initialization.WasmGCInitializerContributor;
import org.teavm.backend.wasm.generate.gc.method.WasmGCFunctionProvider;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCFunctionProvider;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.model.WasmGlobal;
import org.teavm.backend.wasm.model.WasmModule;

View File

@ -15,6 +15,7 @@
*/
package org.teavm.backend.wasm.intrinsics;
import java.util.List;
import org.teavm.ast.Expr;
import org.teavm.backend.wasm.WasmFunctionRepository;
import org.teavm.backend.wasm.WasmFunctionTypes;
@ -56,9 +57,11 @@ public interface WasmIntrinsicManager {
boolean isManagedMethodCall(MethodReference method);
int generateCallSiteId(TextLocation location);
WasmExpression generateRegisterCallSite(int callSite, TextLocation location);
CallSiteIdentifier generateCallSiteId(TextLocation location);
WasmTag getExceptionTag();
interface CallSiteIdentifier {
void generateRegister(List<WasmExpression> target, TextLocation location);
}
}