C backend: fix bugs

This commit is contained in:
Alexey Andreev 2019-02-26 00:10:07 +03:00
parent 2c40c7d56e
commit ade00cc984
11 changed files with 64 additions and 16 deletions

View File

@ -108,6 +108,9 @@ import org.teavm.vm.TeaVMTargetController;
import org.teavm.vm.spi.TeaVMHostExtension;
public class CTarget implements TeaVMTarget, TeaVMCHost {
private static final Set<MethodReference> VIRTUAL_METHODS = new HashSet<>(Arrays.asList(
new MethodReference(Object.class, "clone", Object.class)
));
private TeaVMTargetController controller;
private ClassInitializerInsertionTransformer clinitInsertionTransformer;
private ClassInitializerEliminator classInitializerEliminator;
@ -146,6 +149,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
clinitInsertionTransformer = new ClassInitializerInsertionTransformer(controller.getUnprocessedClassSource());
nullCheckInsertion = new NullCheckInsertion(characteristics);
nullCheckTransformation = new NullCheckTransformation();
controller.addVirtualMethods(VIRTUAL_METHODS::contains);
}
@Override
@ -243,8 +248,9 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
List<Generator> generators = new ArrayList<>();
generators.add(new ArrayGenerator());
GenerationContext context = new GenerationContext(vtableProvider, characteristics, stringPool, nameProvider,
controller.getDiagnostics(), classes, intrinsics, generators);
GenerationContext context = new GenerationContext(vtableProvider, characteristics,
controller.getDependencyInfo(), stringPool, nameProvider, controller.getDiagnostics(), classes,
intrinsics, generators);
BufferedCodeWriter codeWriter = new BufferedCodeWriter();
copyResource(codeWriter, "runtime.c");
@ -362,7 +368,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
}
}
return new VirtualTableProvider(classes, virtualMethods);
return new VirtualTableProvider(classes, virtualMethods, controller::isVirtual);
}
private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) {

View File

@ -28,6 +28,7 @@ import org.teavm.ast.decompilation.Decompiler;
import org.teavm.backend.c.generators.Generator;
import org.teavm.backend.c.generators.GeneratorContext;
import org.teavm.backend.lowlevel.generate.ClassGeneratorUtil;
import org.teavm.dependency.DependencyInfo;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.interop.Address;
import org.teavm.interop.DelegateTo;
@ -672,6 +673,11 @@ public class ClassGenerator {
return context.getClassSource();
}
@Override
public DependencyInfo getDependencies() {
return context.getDependencies();
}
@Override
public String getParameterName(int index) {
return index == 0 ? "_this_" : "local_" + index;

View File

@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import org.teavm.backend.c.generators.Generator;
import org.teavm.backend.c.intrinsic.Intrinsic;
import org.teavm.dependency.DependencyInfo;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference;
@ -30,6 +31,7 @@ import org.teavm.model.lowlevel.Characteristics;
public class GenerationContext {
private VirtualTableProvider virtualTableProvider;
private Characteristics characteristics;
private DependencyInfo dependencies;
private StringPool stringPool;
private NameProvider names;
private Diagnostics diagnostics;
@ -39,10 +41,11 @@ public class GenerationContext {
private Map<MethodReference, Intrinsic> intrinsicCache = new HashMap<>();
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
StringPool stringPool, NameProvider names, Diagnostics diagnostics, ClassReaderSource classSource,
List<Intrinsic> intrinsics, List<Generator> generators) {
DependencyInfo dependencies, StringPool stringPool, NameProvider names, Diagnostics diagnostics,
ClassReaderSource classSource, List<Intrinsic> intrinsics, List<Generator> generators) {
this.virtualTableProvider = virtualTableProvider;
this.characteristics = characteristics;
this.dependencies = dependencies;
this.stringPool = stringPool;
this.names = names;
this.diagnostics = diagnostics;
@ -63,6 +66,10 @@ public class GenerationContext {
return characteristics;
}
public DependencyInfo getDependencies() {
return dependencies;
}
public StringPool getStringPool() {
return stringPool;
}

View File

@ -16,8 +16,12 @@
package org.teavm.backend.c.generators;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.teavm.backend.c.generate.CodeWriter;
import org.teavm.model.ClassReader;
import org.teavm.dependency.MethodDependencyInfo;
import org.teavm.dependency.ValueDependencyInfo;
import org.teavm.model.FieldReference;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
@ -69,14 +73,19 @@ public class ArrayGenerator implements Generator {
writer.println("switch ((flags >> " + RuntimeClass.PRIMITIVE_SHIFT + ") & "
+ RuntimeClass.PRIMITIVE_MASK + ") {").indent();
MethodDependencyInfo dependency = context.getDependencies().getMethod(new MethodReference(Array.class,
"getImpl", Object.class, int.class, Object.class));
ValueDependencyInfo arrayDependency = dependency.getVariable(1);
Set<String> types = new HashSet<>(Arrays.asList(arrayDependency.getTypes()));
for (int i = 0; i < primitiveWrappers.length; ++i) {
String typeName = ValueType.arrayOf(primitiveTypes[i]).toString();
if (!types.contains(typeName)) {
continue;
}
String wrapper = "java.lang." + primitiveWrappers[i];
MethodReference methodRef = new MethodReference(wrapper, "valueOf",
primitiveTypes[i], ValueType.object(wrapper));
ClassReader cls = context.getClassSource().get(methodRef.getClassName());
if (cls == null || cls.getMethod(methodRef.getDescriptor()) == null) {
continue;
}
String type = CodeWriter.strictTypeAsString(primitiveTypes[i]);
writer.println("case " + primitives[i] + ":").indent();

View File

@ -16,6 +16,7 @@
package org.teavm.backend.c.generators;
import org.teavm.backend.c.generate.NameProvider;
import org.teavm.dependency.DependencyInfo;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReaderSource;
@ -26,5 +27,7 @@ public interface GeneratorContext {
ClassReaderSource getClassSource();
DependencyInfo getDependencies();
String getParameterName(int index);
}

View File

@ -794,7 +794,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
}
}
return new VirtualTableProvider(classes, virtualMethods);
return new VirtualTableProvider(classes, virtualMethods, controller::isVirtual);
}
@Override

View File

@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.ElementModifier;
@ -35,7 +36,8 @@ public class VirtualTableProvider {
private Map<String, VirtualTable> virtualTables = new LinkedHashMap<>();
private InterfaceToClassMapping interfaceMapping;
public VirtualTableProvider(ListableClassReaderSource classSource, Set<MethodReference> virtualMethods) {
public VirtualTableProvider(ListableClassReaderSource classSource, Set<MethodReference> virtualMethods,
Predicate<MethodReference> methodCalledVirtually) {
this.classSource = classSource;
interfaceMapping = new InterfaceToClassMapping(classSource);
@ -50,11 +52,11 @@ public class VirtualTableProvider {
}
for (String className : classNames) {
fillClass(className);
fillClass(className, methodCalledVirtually);
}
}
private void fillClass(String className) {
private void fillClass(String className, Predicate<MethodReference> methodCalledVirtually) {
if (virtualTables.containsKey(className)) {
return;
}
@ -66,7 +68,7 @@ public class VirtualTableProvider {
return;
}
if (cls.getParent() != null) {
fillClass(cls.getParent());
fillClass(cls.getParent(), methodCalledVirtually);
VirtualTable parentTable = virtualTables.get(cls.getParent());
for (VirtualTableEntry parentEntry : parentTable.entries.values()) {
VirtualTableEntry entry = new VirtualTableEntry(table, parentEntry.getMethod(),
@ -84,6 +86,9 @@ public class VirtualTableProvider {
MethodReference implementationRef = implementation != null
? implementation.getReference()
: null;
if (implementationRef != null && !methodCalledVirtually.test(implementationRef)) {
implementationRef = null;
}
table.entries.put(method, new VirtualTableEntry(table, method, implementationRef,
table.entries.size()));
}
@ -95,7 +100,7 @@ public class VirtualTableProvider {
continue;
}
VirtualTableEntry entry = table.entries.get(method.getDescriptor());
if (entry != null) {
if (entry != null && methodCalledVirtually.test(method.getReference())) {
entry.implementor = method.getReference();
}
}

View File

@ -812,6 +812,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
+ compileProgressReportStart;
return progressListener.progressReached(progress);
}
@Override
public void addVirtualMethods(Predicate<MethodReference> methods) {
TeaVM.this.addVirtualMethods(methods);
}
};
class PostProcessingClassHolderSource implements ListableClassHolderSource {

View File

@ -18,6 +18,7 @@ package org.teavm.vm;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Predicate;
import org.teavm.cache.CacheStatus;
import org.teavm.common.ServiceRepository;
import org.teavm.dependency.DependencyInfo;
@ -51,4 +52,6 @@ public interface TeaVMTargetController {
boolean isVirtual(MethodReference method);
TeaVMProgressFeedback reportProgress(int progress);
void addVirtualMethods(Predicate<MethodReference> methods);
}

View File

@ -226,6 +226,7 @@ public final class Platform {
}
@Unmanaged
@PluggableDependency(PlatformGenerator.class)
public static String getName(PlatformClass cls) {
return cls.getMetadata().getName();
}

View File

@ -59,6 +59,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
case "getEnumConstants":
method.getResult().propagate(agent.getType("[Ljava/lang/Enum;"));
break;
case "getName":
method.getResult().propagate(agent.getType("java.lang.String"));
break;
}
}