wasm gc: implement ServiceLoader

This commit is contained in:
Alexey Andreev 2024-09-17 15:19:59 +02:00
parent 36f7ec36f3
commit 55ac5d0321
14 changed files with 365 additions and 18 deletions

View File

@ -22,6 +22,7 @@ import java.util.ServiceLoader;
import org.teavm.backend.c.TeaVMCHost;
import org.teavm.backend.javascript.TeaVMJavaScriptHost;
import org.teavm.backend.wasm.TeaVMWasmHost;
import org.teavm.backend.wasm.gc.TeaVMWasmGCHost;
import org.teavm.classlib.ReflectionSupplier;
import org.teavm.classlib.impl.currency.CountriesGenerator;
import org.teavm.classlib.impl.currency.CurrenciesGenerator;
@ -94,6 +95,11 @@ public class JCLPlugin implements TeaVMPlugin {
if (wasmHost != null) {
wasmHost.add(new ServiceLoaderWasmSupport());
}
var wasmGCHost = host.getExtension(TeaVMWasmGCHost.class);
if (wasmGCHost != null) {
wasmGCHost.addGeneratorFactory(new ServiceLoaderWasmGCSupport());
}
}
if (!isBootstrap()) {

View File

@ -0,0 +1,179 @@
/*
* Copyright 2021 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.classlib.impl;
import java.util.ArrayList;
import java.util.Collection;
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.methods.WasmGCGenerationUtil;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorContext;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorFactory;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorFactoryContext;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.model.WasmGlobal;
import org.teavm.backend.wasm.model.WasmLocal;
import org.teavm.backend.wasm.model.WasmType;
import org.teavm.backend.wasm.model.expression.WasmBlock;
import org.teavm.backend.wasm.model.expression.WasmCall;
import org.teavm.backend.wasm.model.expression.WasmCallReference;
import org.teavm.backend.wasm.model.expression.WasmExpression;
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
import org.teavm.backend.wasm.model.expression.WasmNullBranch;
import org.teavm.backend.wasm.model.expression.WasmNullCondition;
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.WasmSetLocal;
import org.teavm.backend.wasm.model.expression.WasmStructGet;
import org.teavm.backend.wasm.model.expression.WasmStructNewDefault;
import org.teavm.backend.wasm.model.expression.WasmStructSet;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
public class ServiceLoaderWasmGCSupport implements WasmGCCustomGeneratorFactory {
static final MethodDescriptor INIT_METHOD = new MethodDescriptor("<init>", ValueType.VOID);
@Override
public WasmGCCustomGenerator createGenerator(MethodReference methodRef,
WasmGCCustomGeneratorFactoryContext context) {
if (methodRef.getClassName().equals(ServiceLoader.class.getName())
&& methodRef.getName().equals("loadServices")) {
return new ServiceLoaderIntrinsic(context.services().getService(ServiceLoaderInformation.class));
}
return null;
}
static class ServiceLoaderIntrinsic implements WasmGCCustomGenerator {
private ServiceLoaderInformation information;
ServiceLoaderIntrinsic(ServiceLoaderInformation information) {
this.information = information;
}
@Override
public void apply(MethodReference method, WasmFunction function, WasmGCCustomGeneratorContext context) {
var initializer = generateInitializer(context);
var emptyInitializer = generateEmptyInitializer(context);
var arrayType = (WasmType.Reference) context.typeMapper().mapType(ValueType.parse(Object[].class));
var servicesFunctionType = context.functionTypes().of(arrayType);
var classLocal = new WasmLocal(context.typeMapper().mapType(ValueType.parse(Class.class)));
function.add(classLocal);
var classStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
var initializerGlobalName = context.names().topLevel("teavm@initializeServicesRef");
var global = new WasmGlobal(initializerGlobalName, initializer.getType().getReference(),
new WasmFunctionReference(initializer));
context.module().globals.add(global);
initializer.getBody().add(0, new WasmSetGlobal(global, new WasmFunctionReference(emptyInitializer)));
function.getBody().add(new WasmCallReference(new WasmGetGlobal(global), initializer.getType()));
var block = new WasmBlock(false);
var servicesFunctionRef = new WasmStructGet(classStruct, new WasmGetLocal(classLocal),
context.classInfoProvider().getServicesOffset());
var nullCheckedRef = new WasmNullBranch(WasmNullCondition.NULL, servicesFunctionRef, block);
var getServices = new WasmCallReference(nullCheckedRef, servicesFunctionType);
block.getBody().add(new WasmReturn(getServices));
function.getBody().add(block);
function.getBody().add(new WasmNullConstant(arrayType));
}
private WasmFunction generateInitializer(WasmGCCustomGeneratorContext context) {
var function = new WasmFunction(context.functionTypes().of(null));
function.setReferenced(true);
function.setName(context.names().topLevel("teavm@initializeServices"));
context.module().functions.add(function);
var serviceTypes = information.serviceTypes();
var classStruct = context.classInfoProvider().getClassInfo("java.lang.Class").getStructure();
var fieldIndex = context.classInfoProvider().getServicesOffset();
for (var serviceType : serviceTypes) {
var implementations = information.serviceImplementations(serviceType);
var providerFunction = generateServiceProvider(context, serviceType, implementations);
var classInfo = context.classInfoProvider().getClassInfo(serviceType);
var classRef = new WasmGetGlobal(classInfo.getPointer());
var providerRef = new WasmFunctionReference(providerFunction);
function.getBody().add(new WasmStructSet(classStruct, classRef, fieldIndex, providerRef));
}
return function;
}
private WasmFunction generateServiceProvider(WasmGCCustomGeneratorContext context,
String interfaceName, Collection<? extends String> implementations) {
var functionType = context.functionTypes().of(context.typeMapper().mapType(
ValueType.parse(Object[].class)));
var function = new WasmFunction(functionType);
function.setName(context.names().topLevel(context.names().suggestForClass(interfaceName) + "@services"));
function.setReferenced(true);
context.module().functions.add(function);
var tempVars = new TemporaryVariablePool(function);
var util = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
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>();
for (var implementationName : implementations) {
items.add(instantiateService(context, function, implementationName));
}
return items;
}, null, null, function.getBody());
return function;
}
private WasmExpression instantiateService(WasmGCCustomGeneratorContext context,
WasmFunction function, String implementationName) {
var implementationInfo = context.classInfoProvider().getClassInfo(implementationName);
var block = new WasmBlock(false);
block.setType(context.typeMapper().mapType(ValueType.parse(Object.class)));
var tmpVar = new WasmLocal(implementationInfo.getType());
function.add(tmpVar);
var structNew = new WasmSetLocal(tmpVar, new WasmStructNewDefault(
implementationInfo.getStructure()));
block.getBody().add(structNew);
var initClassField = new WasmStructSet(implementationInfo.getStructure(), new WasmGetLocal(tmpVar),
WasmGCClassInfoProvider.CLASS_FIELD_OFFSET, new WasmGetGlobal(implementationInfo.getPointer()));
block.getBody().add(initClassField);
var constructor = context.functions().forInstanceMethod(
new MethodReference(implementationName, INIT_METHOD));
block.getBody().add(new WasmCall(constructor, new WasmGetLocal(tmpVar)));
block.getBody().add(new WasmGetLocal(tmpVar));
return block;
}
private WasmFunction generateEmptyInitializer(WasmGCCustomGeneratorContext context) {
var function = new WasmFunction(context.functionTypes().of(null));
function.setReferenced(true);
function.setName(context.names().topLevel("teavm@emptyServicesInitializer"));
context.module().functions.add(function);
function.getBody().add(new WasmReturn());
return function;
}
}
}

View File

@ -15,6 +15,7 @@
*/
package org.teavm.classlib.java.util;
import org.teavm.classlib.PlatformDetector;
import org.teavm.classlib.java.lang.*;
import org.teavm.platform.PlatformClass;
@ -45,7 +46,9 @@ public final class TServiceLoader<S> extends TObject implements TIterable<S> {
}
public static <S> TServiceLoader<S> load(TClass<S> service) {
return new TServiceLoader<>(doLoadServices(service.getPlatformClass()));
return new TServiceLoader<>(PlatformDetector.isWebAssemblyGC()
? doLoadServices(service)
: doLoadServices(service.getPlatformClass()));
}
public static <S> TServiceLoader<S> load(TClass<S> service, @SuppressWarnings("unused") TClassLoader loader) {
@ -66,6 +69,16 @@ public final class TServiceLoader<S> extends TObject implements TIterable<S> {
private static native Object[] loadServices(PlatformClass cls);
private static Object[] doLoadServices(TClass<?> cls) {
Object[] result = loadServices(cls);
if (result == null) {
result = new Object[0];
}
return result;
}
private static native Object[] loadServices(TClass<?> cls);
public void reload() {
// Do nothing, services are bound at build time
}

View File

@ -25,6 +25,8 @@ import org.teavm.backend.wasm.gc.TeaVMWasmGCHost;
import org.teavm.backend.wasm.gc.WasmGCDependencies;
import org.teavm.backend.wasm.generate.gc.WasmGCDeclarationsGenerator;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCCustomTypeMapperFactory;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorFactory;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerators;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsic;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsicFactory;
@ -62,6 +64,8 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
private List<WasmGCIntrinsicFactory> intrinsicFactories = new ArrayList<>();
private Map<MethodReference, WasmGCIntrinsic> customIntrinsics = new HashMap<>();
private List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories = new ArrayList<>();
private Map<MethodReference, WasmGCCustomGenerator> customCustomGenerators = new HashMap<>();
private List<WasmGCCustomGeneratorFactory> customGeneratorFactories = new ArrayList<>();
public void setObfuscated(boolean obfuscated) {
this.obfuscated = obfuscated;
@ -81,6 +85,16 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
customIntrinsics.put(method, intrinsic);
}
@Override
public void addGeneratorFactory(WasmGCCustomGeneratorFactory factory) {
customGeneratorFactories.add(factory);
}
@Override
public void addGenerator(MethodReference method, WasmGCCustomGenerator generator) {
customCustomGenerators.put(method, generator);
}
@Override
public void addCustomTypeMapperFactory(WasmGCCustomTypeMapperFactory customTypeMapperFactory) {
customTypeMapperFactories.add(customTypeMapperFactory);
@ -151,8 +165,9 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
@Override
public void emit(ListableClassHolderSource classes, BuildTarget buildTarget, String outputName) throws IOException {
var module = new WasmModule();
var customGenerators = new WasmGCCustomGenerators();
var intrinsics = new WasmGCIntrinsics(classes, intrinsicFactories, customIntrinsics);
var customGenerators = new WasmGCCustomGenerators(classes, controller.getServices(),
customGeneratorFactories, customCustomGenerators);
var intrinsics = new WasmGCIntrinsics(classes, controller.getServices(), intrinsicFactories, customIntrinsics);
var declarationsGenerator = new WasmGCDeclarationsGenerator(
module,
classes,

View File

@ -16,6 +16,8 @@
package org.teavm.backend.wasm.gc;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCCustomTypeMapperFactory;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGenerator;
import org.teavm.backend.wasm.generators.gc.WasmGCCustomGeneratorFactory;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsic;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsicFactory;
import org.teavm.model.MethodReference;
@ -26,5 +28,9 @@ public interface TeaVMWasmGCHost extends TeaVMHostExtension {
void addIntrinsic(MethodReference method, WasmGCIntrinsic intrinsic);
void addGeneratorFactory(WasmGCCustomGeneratorFactory factory);
void addGenerator(MethodReference method, WasmGCCustomGenerator generator);
void addCustomTypeMapperFactory(WasmGCCustomTypeMapperFactory customTypeMapperFactory);
}

View File

@ -83,6 +83,7 @@ public class WasmGCDeclarationsGenerator {
module,
classes,
hierarchy,
dependencyInfo,
functionTypes,
tags,
metadataRequirements,

View File

@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
@ -75,6 +76,7 @@ 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.backend.wasm.runtime.WasmGCSupport;
import org.teavm.dependency.DependencyInfo;
import org.teavm.model.ClassHierarchy;
import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource;
@ -143,6 +145,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
private int arrayLengthOffset = -1;
private int arrayGetOffset = -1;
private int cloneOffset = -1;
private int servicesOffset = -1;
private WasmStructure arrayVirtualTableStruct;
private WasmFunction arrayGetObjectFunction;
private WasmFunction arrayLengthObjectFunction;
@ -150,9 +153,10 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
private WasmFunctionType arrayLengthType;
private List<WasmStructure> nonInitializedStructures = new ArrayList<>();
private WasmArray objectArrayType;
private boolean hasLoadServices;
public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
ClassHierarchy hierarchy,
ClassHierarchy hierarchy, DependencyInfo dependencyInfo,
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
ClassMetadataRequirements metadataRequirements, WasmGCVirtualTableProvider virtualTables,
BaseWasmFunctionRepository functionProvider, WasmGCNameProvider names,
@ -177,6 +181,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
typeMapper.setCustomTypeMappers(customTypeMapperFactories.stream()
.map(factory -> factory.createTypeMapper(customTypeMapperFactoryContext))
.collect(Collectors.toList()));
var loadServicesMethod = dependencyInfo.getMethod(new MethodReference(ServiceLoader.class, "loadServices",
Class.class, Object[].class));
if (loadServicesMethod != null && loadServicesMethod.isUsed()) {
hasLoadServices = true;
}
}
private WasmGCCustomTypeMapperFactoryContext customTypeMapperFactoryContext() {
@ -443,6 +453,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
return cloneOffset;
}
@Override
public int getServicesOffset() {
standardClasses.classClass().getStructure().init();
return servicesOffset;
}
private void initPrimitiveClass(WasmGCClassInfo classInfo, ValueType.Primitive type) {
classInfo.initializer = target -> {
int kind;
@ -1152,6 +1168,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
cloneOffset = fields.size();
fields.add(createClassField(functionTypes.of(standardClasses.objectClass().getType(),
standardClasses.objectClass().getType()).getReference().asStorage(), "clone"));
if (hasLoadServices) {
servicesOffset = fields.size();
var serviceFunctionType = functionTypes.of(getClassInfo(ValueType.parse(Object[].class)).getType());
fields.add(createClassField(serviceFunctionType.getReference().asStorage(), "services"));
}
if (metadataRequirements.hasEnumConstants()) {
enumConstantsFunctionOffset = fields.size();
var enumArrayType = getClassInfo(ValueType.arrayOf(ValueType.object("java.lang.Enum"))).getType();

View File

@ -67,6 +67,8 @@ public interface WasmGCClassInfoProvider {
int getCloneOffset();
int getServicesOffset();
default WasmGCClassInfo getClassInfo(String name) {
return getClassInfo(ValueType.object(name));
}

View File

@ -28,6 +28,7 @@ import org.teavm.ast.decompilation.Decompiler;
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.gc.PreciseTypeInference;
import org.teavm.backend.wasm.gc.PreciseValueType;
import org.teavm.backend.wasm.gc.WasmGCVariableCategoryProvider;
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
@ -269,6 +270,9 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
var localVar = ast.getVariables().get(i);
var representative = method.getProgram().variableAt(variableRepresentatives[i]);
var inferredType = typeInference.typeOf(representative);
if (inferredType == null) {
inferredType = new PreciseValueType(ValueType.object("java.lang.Object"), false);
}
var type = !inferredType.isArrayUnwrap
? typeMapper.mapType(inferredType.valueType)
: classInfoProvider.getClassInfo(inferredType.valueType).getArray().getReference();

View File

@ -0,0 +1,22 @@
/*
* 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.generators.gc;
import org.teavm.model.MethodReference;
public interface WasmGCCustomGeneratorFactory {
WasmGCCustomGenerator createGenerator(MethodReference methodRef, WasmGCCustomGeneratorFactoryContext context);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2024 konsoletyper.
*
* 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.generators.gc;
import org.teavm.common.ServiceRepository;
import org.teavm.model.ClassReaderSource;
public interface WasmGCCustomGeneratorFactoryContext {
ClassReaderSource classes();
ServiceRepository services();
}

View File

@ -17,36 +17,46 @@ package org.teavm.backend.wasm.generators.gc;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCCustomGeneratorProvider;
import org.teavm.backend.wasm.runtime.WasmGCSupport;
import org.teavm.common.ServiceRepository;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference;
public class WasmGCCustomGenerators implements WasmGCCustomGeneratorProvider {
private Map<MethodReference, WasmGCCustomGenerator> generators = new HashMap<>();
private List<WasmGCCustomGeneratorFactory> factories;
private Map<MethodReference, Container> generators = new HashMap<>();
private ClassReaderSource classes;
private ServiceRepository services;
public WasmGCCustomGenerators() {
public WasmGCCustomGenerators(ClassReaderSource classes, ServiceRepository services,
List<WasmGCCustomGeneratorFactory> factories,
Map<MethodReference, WasmGCCustomGenerator> generators) {
this.factories = List.copyOf(factories);
this.classes = classes;
this.services = services;
fillClass();
fillStringPool();
fillSystem();
fillArray();
for (var entry : generators.entrySet()) {
add(entry.getKey(), entry.getValue());
}
}
private void fillClass() {
var classGenerators = new ClassGenerators();
generators.put(new MethodReference(Class.class, "isAssignableFrom", Class.class, boolean.class),
classGenerators);
add(new MethodReference(Class.class, "isAssignableFrom", Class.class, boolean.class), classGenerators);
}
private void fillStringPool() {
generators.put(
new MethodReference(WasmGCSupport.class, "nextByte", byte.class),
new WasmGCStringPoolGenerator()
);
add(new MethodReference(WasmGCSupport.class, "nextByte", byte.class), new WasmGCStringPoolGenerator());
}
private void fillSystem() {
generators.put(
add(
new MethodReference(System.class, "doArrayCopy", Object.class, int.class, Object.class,
int.class, int.class, void.class),
new SystemDoArrayCopyGenerator()
@ -55,12 +65,44 @@ public class WasmGCCustomGenerators implements WasmGCCustomGeneratorProvider {
private void fillArray() {
var arrayGenerator = new ArrayGenerator();
generators.put(new MethodReference(Array.class, "newInstanceImpl", Class.class, int.class, Object.class),
arrayGenerator);
add(new MethodReference(Array.class, "newInstanceImpl", Class.class, int.class, Object.class), arrayGenerator);
}
@Override
public WasmGCCustomGenerator get(MethodReference method) {
return generators.get(method);
var result = generators.get(method);
if (result == null) {
WasmGCCustomGenerator generator = null;
for (var factory : factories) {
generator = factory.createGenerator(method, factoryContext);
}
result = new Container(generator);
generators.put(method, result);
}
return result.generator;
}
private void add(MethodReference method, WasmGCCustomGenerator generator) {
generators.put(method, new Container(generator));
}
private static class Container {
final WasmGCCustomGenerator generator;
Container(WasmGCCustomGenerator generator) {
this.generator = generator;
}
}
private WasmGCCustomGeneratorFactoryContext factoryContext = new WasmGCCustomGeneratorFactoryContext() {
@Override
public ClassReaderSource classes() {
return classes;
}
@Override
public ServiceRepository services() {
return services;
}
};
}

View File

@ -15,8 +15,11 @@
*/
package org.teavm.backend.wasm.intrinsics.gc;
import org.teavm.common.ServiceRepository;
import org.teavm.model.ClassReaderSource;
public interface WasmGCIntrinsicFactoryContext {
ClassReaderSource classes();
ServiceRepository services();
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import org.teavm.backend.wasm.WasmRuntime;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCIntrinsicProvider;
import org.teavm.backend.wasm.model.expression.WasmIntType;
import org.teavm.common.ServiceRepository;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
@ -30,10 +31,12 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
private Map<MethodReference, IntrinsicContainer> intrinsics = new HashMap<>();
private List<WasmGCIntrinsicFactory> factories;
private ClassReaderSource classes;
private ServiceRepository services;
public WasmGCIntrinsics(ClassReaderSource classes, List<WasmGCIntrinsicFactory> factories,
Map<MethodReference, WasmGCIntrinsic> customIntrinsics) {
public WasmGCIntrinsics(ClassReaderSource classes, ServiceRepository services,
List<WasmGCIntrinsicFactory> factories, Map<MethodReference, WasmGCIntrinsic> customIntrinsics) {
this.classes = classes;
this.services = services;
this.factories = List.copyOf(factories);
factories = List.copyOf(factories);
fillWasmRuntime();
@ -179,5 +182,10 @@ public class WasmGCIntrinsics implements WasmGCIntrinsicProvider {
public ClassReaderSource classes() {
return classes;
}
@Override
public ServiceRepository services() {
return services;
}
};
}