Fix WebAssembly codegen

This commit is contained in:
Alexey Andreev 2017-10-24 00:04:57 +03:00
parent fecc087993
commit 775b5324b3
5 changed files with 30 additions and 6 deletions

View File

@ -297,7 +297,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
vtableProvider, tagRegistry, stringPool); vtableProvider, tagRegistry, stringPool);
context.addIntrinsic(new AddressIntrinsic(classGenerator)); context.addIntrinsic(new AddressIntrinsic(classGenerator));
context.addIntrinsic(new StructureIntrinsic(classGenerator)); context.addIntrinsic(new StructureIntrinsic(classes, classGenerator));
context.addIntrinsic(new FunctionIntrinsic(classGenerator)); context.addIntrinsic(new FunctionIntrinsic(classGenerator));
WasmRuntimeIntrinsic wasmRuntimeIntrinsic = new WasmRuntimeIntrinsic(); WasmRuntimeIntrinsic wasmRuntimeIntrinsic = new WasmRuntimeIntrinsic();
context.addIntrinsic(wasmRuntimeIntrinsic); context.addIntrinsic(wasmRuntimeIntrinsic);

View File

@ -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.WasmIntBinaryOperation;
import org.teavm.backend.wasm.model.expression.WasmIntType; import org.teavm.backend.wasm.model.expression.WasmIntType;
import org.teavm.interop.Structure; import org.teavm.interop.Structure;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
public class StructureIntrinsic implements WasmIntrinsic { public class StructureIntrinsic implements WasmIntrinsic {
private ClassReaderSource classSource;
private WasmClassGenerator classGenerator; private WasmClassGenerator classGenerator;
public StructureIntrinsic(WasmClassGenerator classGenerator) { public StructureIntrinsic(ClassReaderSource classSource, WasmClassGenerator classGenerator) {
this.classSource = classSource;
this.classGenerator = classGenerator; this.classGenerator = classGenerator;
} }
@Override @Override
public boolean isApplicable(MethodReference methodReference) { 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 @Override

View File

@ -67,7 +67,7 @@ public class CachedMapper<T, R> implements Mapper<T, R> {
} }
public Collection<T> getCachedPreimages() { public Collection<T> getCachedPreimages() {
return new HashSet<>(cache.keySet()); return new LinkedHashSet<>(cache.keySet());
} }
public void addKeyListener(KeyListener<T> listener) { public void addKeyListener(KeyListener<T> listener) {

View File

@ -41,6 +41,7 @@ import org.teavm.model.instructions.PutFieldInstruction;
public class Linker { public class Linker {
private Set<MethodReference> methodsToPreserve = new HashSet<>(); private Set<MethodReference> methodsToPreserve = new HashSet<>();
private Set<String> additionalClasses = new HashSet<>();
public void prepare(DependencyInfo dependency, ClassReader cls) { public void prepare(DependencyInfo dependency, ClassReader cls) {
for (MethodReader method : cls.getMethods().toArray(new MethodReader[0])) { 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, public void invoke(VariableReader receiver, VariableReader instance, MethodReference method,
List<? extends VariableReader> arguments, InvocationType type) { List<? extends VariableReader> arguments, InvocationType type) {
methodsToPreserve.add(method); methodsToPreserve.add(method);
additionalClasses.add(method.getClassName());
} }
}); });
} }
} }
public Set<String> getAdditionalClasses() {
return additionalClasses;
}
public void link(DependencyInfo dependency, ClassHolder cls) { public void link(DependencyInfo dependency, ClassHolder cls) {
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { 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); MethodDependencyInfo methodDep = dependency.getMethod(methodRef);
if (methodDep == null) { if (methodDep == null) {
if (methodsToPreserve.contains(methodRef)) { if (methodsToPreserve.contains(methodRef)) {

View File

@ -22,10 +22,12 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.teavm.cache.NoCache; import org.teavm.cache.NoCache;
import org.teavm.common.ServiceRepository; import org.teavm.common.ServiceRepository;
@ -409,7 +411,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
return cutClasses; return cutClasses;
} }
for (String className : dependency.getReachableClasses()) { Set<String> allClasses = new LinkedHashSet<>(dependency.getReachableClasses());
allClasses.addAll(linker.getAdditionalClasses());
for (String className : allClasses) {
ClassReader clsReader = dependency.getClassSource().get(className); ClassReader clsReader = dependency.getClassSource().get(className);
if (clsReader == null) { if (clsReader == null) {
continue; continue;