Skip to content

Commit

Permalink
wasm gc: implement resources
Browse files Browse the repository at this point in the history
  • Loading branch information
konsoletyper committed Sep 5, 2024
1 parent 29dec09 commit 6fb8f94
Show file tree
Hide file tree
Showing 20 changed files with 656 additions and 100 deletions.
31 changes: 29 additions & 2 deletions core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@
package org.teavm.backend.wasm;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.WasmGCCustomGenerators;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsic;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsicFactory;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsics;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.render.WasmBinaryRenderer;
Expand All @@ -33,6 +40,7 @@
import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.ListableClassHolderSource;
import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;
import org.teavm.model.Program;
import org.teavm.model.transformation.BoundCheckInsertion;
import org.teavm.model.transformation.NullCheckFilter;
Expand All @@ -43,16 +51,34 @@
import org.teavm.vm.TeaVMTargetController;
import org.teavm.vm.spi.TeaVMHostExtension;

public class WasmGCTarget implements TeaVMTarget {
public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
private TeaVMTargetController controller;
private NullCheckInsertion nullCheckInsertion;
private BoundCheckInsertion boundCheckInsertion = new BoundCheckInsertion();
private boolean obfuscated;
private List<WasmGCIntrinsicFactory> intrinsicFactories = new ArrayList<>();
private Map<MethodReference, WasmGCIntrinsic> customIntrinsics = new HashMap<>();
private List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories = new ArrayList<>();

public void setObfuscated(boolean obfuscated) {
this.obfuscated = obfuscated;
}

@Override
public void addIntrinsicFactory(WasmGCIntrinsicFactory intrinsicFactory) {
intrinsicFactories.add(intrinsicFactory);
}

@Override
public void addIntrinsic(MethodReference method, WasmGCIntrinsic intrinsic) {
customIntrinsics.put(method, intrinsic);
}

@Override
public void addCustomTypeMapperFactory(WasmGCCustomTypeMapperFactory customTypeMapperFactory) {
customTypeMapperFactories.add(customTypeMapperFactory);
}

@Override
public void setController(TeaVMTargetController controller) {
this.controller = controller;
Expand Down Expand Up @@ -114,7 +140,7 @@ public boolean isAsyncSupported() {
public void emit(ListableClassHolderSource classes, BuildTarget buildTarget, String outputName) throws IOException {
var module = new WasmModule();
var customGenerators = new WasmGCCustomGenerators();
var intrinsics = new WasmGCIntrinsics();
var intrinsics = new WasmGCIntrinsics(classes, intrinsicFactories, customIntrinsics);
var declarationsGenerator = new WasmGCDeclarationsGenerator(
module,
classes,
Expand All @@ -123,6 +149,7 @@ public void emit(ListableClassHolderSource classes, BuildTarget buildTarget, Str
controller.getDiagnostics(),
customGenerators,
intrinsics,
customTypeMapperFactories,
controller::isVirtual
);
declarationsGenerator.setFriendlyToDebugger(controller.isFriendlyToDebugger());
Expand Down
30 changes: 30 additions & 0 deletions core/src/main/java/org/teavm/backend/wasm/gc/TeaVMWasmGCHost.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.gc;

import org.teavm.backend.wasm.generate.gc.classes.WasmGCCustomTypeMapperFactory;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsic;
import org.teavm.backend.wasm.intrinsics.gc.WasmGCIntrinsicFactory;
import org.teavm.model.MethodReference;
import org.teavm.vm.spi.TeaVMHostExtension;

public interface TeaVMWasmGCHost extends TeaVMHostExtension {
void addIntrinsicFactory(WasmGCIntrinsicFactory intrinsicFactory);

void addIntrinsic(MethodReference method, WasmGCIntrinsic intrinsic);

void addCustomTypeMapperFactory(WasmGCCustomTypeMapperFactory customTypeMapperFactory);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassGenerator;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCCustomTypeMapper;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCCustomTypeMapperFactory;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCSupertypeFunctionProvider;
import org.teavm.backend.wasm.generate.gc.classes.WasmGCTypeMapper;
import org.teavm.backend.wasm.generate.gc.methods.WasmGCCustomGeneratorProvider;
Expand Down Expand Up @@ -54,6 +56,7 @@ public WasmGCDeclarationsGenerator(
Diagnostics diagnostics,
WasmGCCustomGeneratorProvider customGenerators,
WasmGCIntrinsicProvider intrinsics,
List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories,
Predicate<MethodReference> isVirtual
) {
this.module = module;
Expand Down Expand Up @@ -84,7 +87,8 @@ public WasmGCDeclarationsGenerator(
virtualTables,
methodGenerator,
names,
classInitializerInfo
classInitializerInfo,
customTypeMapperFactories
);
methodGenerator.setClassInfoProvider(classGenerator);
methodGenerator.setStrings(classGenerator.strings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Map;
import java.util.Queue;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.teavm.backend.wasm.BaseWasmFunctionRepository;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTable;
Expand Down Expand Up @@ -137,7 +138,8 @@ public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
WasmFunctionTypes functionTypes, TagRegistry tagRegistry,
ClassMetadataRequirements metadataRequirements, WasmGCVirtualTableProvider virtualTables,
BaseWasmFunctionRepository functionProvider, WasmGCNameProvider names,
ClassInitializerInfo classInitializerInfo) {
ClassInitializerInfo classInitializerInfo,
List<WasmGCCustomTypeMapperFactory> customTypeMapperFactories) {
this.module = module;
this.classSource = classSource;
this.functionTypes = functionTypes;
Expand All @@ -152,6 +154,39 @@ public WasmGCClassGenerator(WasmModule module, ClassReaderSource classSource,
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this, names);
typeMapper = new WasmGCTypeMapper(classSource, this, functionTypes, module);
var customTypeMapperFactoryContext = customTypeMapperFactoryContext();
typeMapper.setCustomTypeMappers(customTypeMapperFactories.stream()
.map(factory -> factory.createTypeMapper(customTypeMapperFactoryContext))
.collect(Collectors.toList()));
}

private WasmGCCustomTypeMapperFactoryContext customTypeMapperFactoryContext() {
return new WasmGCCustomTypeMapperFactoryContext() {
@Override
public ClassReaderSource classes() {
return classSource;
}

@Override
public WasmModule module() {
return module;
}

@Override
public WasmGCClassInfoProvider classInfoProvider() {
return WasmGCClassGenerator.this;
}

@Override
public WasmGCNameProvider names() {
return names;
}

@Override
public WasmGCTypeMapper typeMapper() {
return typeMapper;
}
};
}

public WasmGCSupertypeFunctionProvider getSupertypeProvider() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.generate.gc.classes;

import org.teavm.backend.wasm.model.WasmType;

public interface WasmGCCustomTypeMapper {
WasmType map(String className);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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.gc.classes;

public interface WasmGCCustomTypeMapperFactory {
WasmGCCustomTypeMapper createTypeMapper(WasmGCCustomTypeMapperFactoryContext context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.gc.classes;

import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.model.ClassReaderSource;

public interface WasmGCCustomTypeMapperFactoryContext {
ClassReaderSource classes();

WasmModule module();

WasmGCClassInfoProvider classInfoProvider();

WasmGCTypeMapper typeMapper();

WasmGCNameProvider names();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package org.teavm.backend.wasm.generate.gc.classes;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.teavm.backend.wasm.WasmFunctionTypes;
import org.teavm.backend.wasm.model.WasmArray;
import org.teavm.backend.wasm.model.WasmFunctionType;
import org.teavm.backend.wasm.model.WasmModule;
import org.teavm.backend.wasm.model.WasmPackedType;
Expand All @@ -31,6 +34,8 @@ public class WasmGCTypeMapper {
private WasmGCClassInfoProvider classInfoProvider;
private WasmFunctionTypes functionTypes;
private WasmModule module;
private List<WasmGCCustomTypeMapper> customTypeMappers;
private Map<String, WasmType> typeCache = new HashMap<>();

WasmGCTypeMapper(ClassReaderSource classes, WasmGCClassInfoProvider classInfoProvider,
WasmFunctionTypes functionTypes, WasmModule module) {
Expand All @@ -40,6 +45,10 @@ public class WasmGCTypeMapper {
this.module = module;
}

void setCustomTypeMappers(List<WasmGCCustomTypeMapper> customTypeMappers) {
this.customTypeMappers = List.copyOf(customTypeMappers);
}

public WasmStorageType mapStorageType(ValueType type) {
if (type instanceof ValueType.Primitive) {
switch (((ValueType.Primitive) type).getKind()) {
Expand Down Expand Up @@ -87,11 +96,24 @@ public WasmType mapType(ValueType type) {
return null;
} else if (type instanceof ValueType.Object) {
var className = ((ValueType.Object) type).getClassName();
var cls = classes.get(className);
if (cls == null) {
className = "java.lang.Object";
var result = typeCache.get(className);
if (result == null) {
for (var customMapper : customTypeMappers) {
result = customMapper.map(className);
if (result != null) {
break;
}
}
if (result == null) {
var cls = classes.get(className);
if (cls == null) {
className = "java.lang.Object";
}
result = classInfoProvider.getClassInfo(className).getType();
typeCache.put(className, result);
}
}
return classInfoProvider.getClassInfo(className).getType();
return result;
} else if (type instanceof ValueType.Array) {
var degree = 0;
while (type instanceof ValueType.Array) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.intrinsics.gc;

import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;

public interface WasmGCIntrinsicFactory {
WasmGCIntrinsic createIntrinsic(MethodReference methodRef, WasmGCIntrinsicFactoryContext context);
}
Original file line number Diff line number Diff line change
@@ -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.intrinsics.gc;

import org.teavm.model.ClassReaderSource;

public interface WasmGCIntrinsicFactoryContext {
ClassReaderSource classes();
}
Loading

0 comments on commit 6fb8f94

Please sign in to comment.