From 775b5324b35b998e0d5ff17803ab1cfb79d5152e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 24 Oct 2017 00:04:57 +0300 Subject: [PATCH] Fix WebAssembly codegen --- .../java/org/teavm/backend/wasm/WasmTarget.java | 2 +- .../wasm/intrinsics/StructureIntrinsic.java | 17 +++++++++++++++-- .../java/org/teavm/common/CachedMapper.java | 2 +- .../main/java/org/teavm/dependency/Linker.java | 8 +++++++- core/src/main/java/org/teavm/vm/TeaVM.java | 7 ++++++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java index 20cda3548..3b8e90b02 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java @@ -297,7 +297,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost { vtableProvider, tagRegistry, stringPool); context.addIntrinsic(new AddressIntrinsic(classGenerator)); - context.addIntrinsic(new StructureIntrinsic(classGenerator)); + context.addIntrinsic(new StructureIntrinsic(classes, classGenerator)); context.addIntrinsic(new FunctionIntrinsic(classGenerator)); WasmRuntimeIntrinsic wasmRuntimeIntrinsic = new WasmRuntimeIntrinsic(); context.addIntrinsic(wasmRuntimeIntrinsic); diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/StructureIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/StructureIntrinsic.java index 962ab433e..a1b61833a 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/StructureIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/StructureIntrinsic.java @@ -24,19 +24,32 @@ import org.teavm.backend.wasm.model.expression.WasmIntBinary; import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation; import org.teavm.backend.wasm.model.expression.WasmIntType; import org.teavm.interop.Structure; +import org.teavm.model.ClassReaderSource; import org.teavm.model.MethodReference; import org.teavm.model.ValueType; public class StructureIntrinsic implements WasmIntrinsic { + private ClassReaderSource classSource; private WasmClassGenerator classGenerator; - public StructureIntrinsic(WasmClassGenerator classGenerator) { + public StructureIntrinsic(ClassReaderSource classSource, WasmClassGenerator classGenerator) { + this.classSource = classSource; this.classGenerator = classGenerator; } @Override public boolean isApplicable(MethodReference methodReference) { - return methodReference.getClassName().equals(Structure.class.getName()); + if (!classSource.isSuperType(Structure.class.getName(), methodReference.getClassName()).orElse(false)) { + return false; + } + switch (methodReference.getName()) { + case "toAddress": + case "cast": + case "sizeOf": + case "add": + return true; + } + return false; } @Override diff --git a/core/src/main/java/org/teavm/common/CachedMapper.java b/core/src/main/java/org/teavm/common/CachedMapper.java index 702131b47..634d8022a 100644 --- a/core/src/main/java/org/teavm/common/CachedMapper.java +++ b/core/src/main/java/org/teavm/common/CachedMapper.java @@ -67,7 +67,7 @@ public class CachedMapper implements Mapper { } public Collection getCachedPreimages() { - return new HashSet<>(cache.keySet()); + return new LinkedHashSet<>(cache.keySet()); } public void addKeyListener(KeyListener listener) { diff --git a/core/src/main/java/org/teavm/dependency/Linker.java b/core/src/main/java/org/teavm/dependency/Linker.java index be2c7af4f..a3dac8192 100644 --- a/core/src/main/java/org/teavm/dependency/Linker.java +++ b/core/src/main/java/org/teavm/dependency/Linker.java @@ -41,6 +41,7 @@ import org.teavm.model.instructions.PutFieldInstruction; public class Linker { private Set methodsToPreserve = new HashSet<>(); + private Set additionalClasses = new HashSet<>(); public void prepare(DependencyInfo dependency, ClassReader cls) { for (MethodReader method : cls.getMethods().toArray(new MethodReader[0])) { @@ -59,14 +60,19 @@ public class Linker { public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, List arguments, InvocationType type) { methodsToPreserve.add(method); + additionalClasses.add(method.getClassName()); } }); } } + public Set getAdditionalClasses() { + return additionalClasses; + } + public void link(DependencyInfo dependency, ClassHolder cls) { for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { - MethodReference methodRef = new MethodReference(cls.getName(), method.getDescriptor()); + MethodReference methodRef = method.getReference(); MethodDependencyInfo methodDep = dependency.getMethod(methodRef); if (methodDep == null) { if (methodsToPreserve.contains(methodRef)) { diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java index 701681b15..5a1bd2f7b 100644 --- a/core/src/main/java/org/teavm/vm/TeaVM.java +++ b/core/src/main/java/org/teavm/vm/TeaVM.java @@ -22,10 +22,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.ServiceLoader; +import java.util.Set; import java.util.stream.Collectors; import org.teavm.cache.NoCache; import org.teavm.common.ServiceRepository; @@ -409,7 +411,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository { return cutClasses; } - for (String className : dependency.getReachableClasses()) { + Set allClasses = new LinkedHashSet<>(dependency.getReachableClasses()); + allClasses.addAll(linker.getAdditionalClasses()); + + for (String className : allClasses) { ClassReader clsReader = dependency.getClassSource().get(className); if (clsReader == null) { continue;