mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
C backend: fix bugs
This commit is contained in:
parent
2c40c7d56e
commit
ade00cc984
|
@ -108,6 +108,9 @@ import org.teavm.vm.TeaVMTargetController;
|
||||||
import org.teavm.vm.spi.TeaVMHostExtension;
|
import org.teavm.vm.spi.TeaVMHostExtension;
|
||||||
|
|
||||||
public class CTarget implements TeaVMTarget, TeaVMCHost {
|
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 TeaVMTargetController controller;
|
||||||
private ClassInitializerInsertionTransformer clinitInsertionTransformer;
|
private ClassInitializerInsertionTransformer clinitInsertionTransformer;
|
||||||
private ClassInitializerEliminator classInitializerEliminator;
|
private ClassInitializerEliminator classInitializerEliminator;
|
||||||
|
@ -146,6 +149,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
clinitInsertionTransformer = new ClassInitializerInsertionTransformer(controller.getUnprocessedClassSource());
|
clinitInsertionTransformer = new ClassInitializerInsertionTransformer(controller.getUnprocessedClassSource());
|
||||||
nullCheckInsertion = new NullCheckInsertion(characteristics);
|
nullCheckInsertion = new NullCheckInsertion(characteristics);
|
||||||
nullCheckTransformation = new NullCheckTransformation();
|
nullCheckTransformation = new NullCheckTransformation();
|
||||||
|
|
||||||
|
controller.addVirtualMethods(VIRTUAL_METHODS::contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -243,8 +248,9 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
List<Generator> generators = new ArrayList<>();
|
List<Generator> generators = new ArrayList<>();
|
||||||
generators.add(new ArrayGenerator());
|
generators.add(new ArrayGenerator());
|
||||||
|
|
||||||
GenerationContext context = new GenerationContext(vtableProvider, characteristics, stringPool, nameProvider,
|
GenerationContext context = new GenerationContext(vtableProvider, characteristics,
|
||||||
controller.getDiagnostics(), classes, intrinsics, generators);
|
controller.getDependencyInfo(), stringPool, nameProvider, controller.getDiagnostics(), classes,
|
||||||
|
intrinsics, generators);
|
||||||
|
|
||||||
BufferedCodeWriter codeWriter = new BufferedCodeWriter();
|
BufferedCodeWriter codeWriter = new BufferedCodeWriter();
|
||||||
copyResource(codeWriter, "runtime.c");
|
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) {
|
private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.teavm.ast.decompilation.Decompiler;
|
||||||
import org.teavm.backend.c.generators.Generator;
|
import org.teavm.backend.c.generators.Generator;
|
||||||
import org.teavm.backend.c.generators.GeneratorContext;
|
import org.teavm.backend.c.generators.GeneratorContext;
|
||||||
import org.teavm.backend.lowlevel.generate.ClassGeneratorUtil;
|
import org.teavm.backend.lowlevel.generate.ClassGeneratorUtil;
|
||||||
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
|
@ -672,6 +673,11 @@ public class ClassGenerator {
|
||||||
return context.getClassSource();
|
return context.getClassSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DependencyInfo getDependencies() {
|
||||||
|
return context.getDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getParameterName(int index) {
|
public String getParameterName(int index) {
|
||||||
return index == 0 ? "_this_" : "local_" + index;
|
return index == 0 ? "_this_" : "local_" + index;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.backend.c.generators.Generator;
|
import org.teavm.backend.c.generators.Generator;
|
||||||
import org.teavm.backend.c.intrinsic.Intrinsic;
|
import org.teavm.backend.c.intrinsic.Intrinsic;
|
||||||
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -30,6 +31,7 @@ import org.teavm.model.lowlevel.Characteristics;
|
||||||
public class GenerationContext {
|
public class GenerationContext {
|
||||||
private VirtualTableProvider virtualTableProvider;
|
private VirtualTableProvider virtualTableProvider;
|
||||||
private Characteristics characteristics;
|
private Characteristics characteristics;
|
||||||
|
private DependencyInfo dependencies;
|
||||||
private StringPool stringPool;
|
private StringPool stringPool;
|
||||||
private NameProvider names;
|
private NameProvider names;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
|
@ -39,10 +41,11 @@ public class GenerationContext {
|
||||||
private Map<MethodReference, Intrinsic> intrinsicCache = new HashMap<>();
|
private Map<MethodReference, Intrinsic> intrinsicCache = new HashMap<>();
|
||||||
|
|
||||||
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
|
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
|
||||||
StringPool stringPool, NameProvider names, Diagnostics diagnostics, ClassReaderSource classSource,
|
DependencyInfo dependencies, StringPool stringPool, NameProvider names, Diagnostics diagnostics,
|
||||||
List<Intrinsic> intrinsics, List<Generator> generators) {
|
ClassReaderSource classSource, List<Intrinsic> intrinsics, List<Generator> generators) {
|
||||||
this.virtualTableProvider = virtualTableProvider;
|
this.virtualTableProvider = virtualTableProvider;
|
||||||
this.characteristics = characteristics;
|
this.characteristics = characteristics;
|
||||||
|
this.dependencies = dependencies;
|
||||||
this.stringPool = stringPool;
|
this.stringPool = stringPool;
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
|
@ -63,6 +66,10 @@ public class GenerationContext {
|
||||||
return characteristics;
|
return characteristics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DependencyInfo getDependencies() {
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
public StringPool getStringPool() {
|
public StringPool getStringPool() {
|
||||||
return stringPool;
|
return stringPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,12 @@
|
||||||
package org.teavm.backend.c.generators;
|
package org.teavm.backend.c.generators;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
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.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.FieldReference;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
@ -69,14 +73,19 @@ public class ArrayGenerator implements Generator {
|
||||||
|
|
||||||
writer.println("switch ((flags >> " + RuntimeClass.PRIMITIVE_SHIFT + ") & "
|
writer.println("switch ((flags >> " + RuntimeClass.PRIMITIVE_SHIFT + ") & "
|
||||||
+ RuntimeClass.PRIMITIVE_MASK + ") {").indent();
|
+ 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) {
|
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];
|
String wrapper = "java.lang." + primitiveWrappers[i];
|
||||||
MethodReference methodRef = new MethodReference(wrapper, "valueOf",
|
MethodReference methodRef = new MethodReference(wrapper, "valueOf",
|
||||||
primitiveTypes[i], ValueType.object(wrapper));
|
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]);
|
String type = CodeWriter.strictTypeAsString(primitiveTypes[i]);
|
||||||
writer.println("case " + primitives[i] + ":").indent();
|
writer.println("case " + primitives[i] + ":").indent();
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.backend.c.generators;
|
package org.teavm.backend.c.generators;
|
||||||
|
|
||||||
import org.teavm.backend.c.generate.NameProvider;
|
import org.teavm.backend.c.generate.NameProvider;
|
||||||
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
|
||||||
|
@ -26,5 +27,7 @@ public interface GeneratorContext {
|
||||||
|
|
||||||
ClassReaderSource getClassSource();
|
ClassReaderSource getClassSource();
|
||||||
|
|
||||||
|
DependencyInfo getDependencies();
|
||||||
|
|
||||||
String getParameterName(int index);
|
String getParameterName(int index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -794,7 +794,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new VirtualTableProvider(classes, virtualMethods);
|
return new VirtualTableProvider(classes, virtualMethods, controller::isVirtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
|
@ -35,7 +36,8 @@ public class VirtualTableProvider {
|
||||||
private Map<String, VirtualTable> virtualTables = new LinkedHashMap<>();
|
private Map<String, VirtualTable> virtualTables = new LinkedHashMap<>();
|
||||||
private InterfaceToClassMapping interfaceMapping;
|
private InterfaceToClassMapping interfaceMapping;
|
||||||
|
|
||||||
public VirtualTableProvider(ListableClassReaderSource classSource, Set<MethodReference> virtualMethods) {
|
public VirtualTableProvider(ListableClassReaderSource classSource, Set<MethodReference> virtualMethods,
|
||||||
|
Predicate<MethodReference> methodCalledVirtually) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
interfaceMapping = new InterfaceToClassMapping(classSource);
|
interfaceMapping = new InterfaceToClassMapping(classSource);
|
||||||
|
|
||||||
|
@ -50,11 +52,11 @@ public class VirtualTableProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String className : classNames) {
|
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)) {
|
if (virtualTables.containsKey(className)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +68,7 @@ public class VirtualTableProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cls.getParent() != null) {
|
if (cls.getParent() != null) {
|
||||||
fillClass(cls.getParent());
|
fillClass(cls.getParent(), methodCalledVirtually);
|
||||||
VirtualTable parentTable = virtualTables.get(cls.getParent());
|
VirtualTable parentTable = virtualTables.get(cls.getParent());
|
||||||
for (VirtualTableEntry parentEntry : parentTable.entries.values()) {
|
for (VirtualTableEntry parentEntry : parentTable.entries.values()) {
|
||||||
VirtualTableEntry entry = new VirtualTableEntry(table, parentEntry.getMethod(),
|
VirtualTableEntry entry = new VirtualTableEntry(table, parentEntry.getMethod(),
|
||||||
|
@ -84,6 +86,9 @@ public class VirtualTableProvider {
|
||||||
MethodReference implementationRef = implementation != null
|
MethodReference implementationRef = implementation != null
|
||||||
? implementation.getReference()
|
? implementation.getReference()
|
||||||
: null;
|
: null;
|
||||||
|
if (implementationRef != null && !methodCalledVirtually.test(implementationRef)) {
|
||||||
|
implementationRef = null;
|
||||||
|
}
|
||||||
table.entries.put(method, new VirtualTableEntry(table, method, implementationRef,
|
table.entries.put(method, new VirtualTableEntry(table, method, implementationRef,
|
||||||
table.entries.size()));
|
table.entries.size()));
|
||||||
}
|
}
|
||||||
|
@ -95,7 +100,7 @@ public class VirtualTableProvider {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
VirtualTableEntry entry = table.entries.get(method.getDescriptor());
|
VirtualTableEntry entry = table.entries.get(method.getDescriptor());
|
||||||
if (entry != null) {
|
if (entry != null && methodCalledVirtually.test(method.getReference())) {
|
||||||
entry.implementor = method.getReference();
|
entry.implementor = method.getReference();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -812,6 +812,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
+ compileProgressReportStart;
|
+ compileProgressReportStart;
|
||||||
return progressListener.progressReached(progress);
|
return progressListener.progressReached(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addVirtualMethods(Predicate<MethodReference> methods) {
|
||||||
|
TeaVM.this.addVirtualMethods(methods);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PostProcessingClassHolderSource implements ListableClassHolderSource {
|
class PostProcessingClassHolderSource implements ListableClassHolderSource {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.vm;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import org.teavm.cache.CacheStatus;
|
import org.teavm.cache.CacheStatus;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
|
@ -51,4 +52,6 @@ public interface TeaVMTargetController {
|
||||||
boolean isVirtual(MethodReference method);
|
boolean isVirtual(MethodReference method);
|
||||||
|
|
||||||
TeaVMProgressFeedback reportProgress(int progress);
|
TeaVMProgressFeedback reportProgress(int progress);
|
||||||
|
|
||||||
|
void addVirtualMethods(Predicate<MethodReference> methods);
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,7 @@ public final class Platform {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
public static String getName(PlatformClass cls) {
|
public static String getName(PlatformClass cls) {
|
||||||
return cls.getMetadata().getName();
|
return cls.getMetadata().getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
||||||
case "getEnumConstants":
|
case "getEnumConstants":
|
||||||
method.getResult().propagate(agent.getType("[Ljava/lang/Enum;"));
|
method.getResult().propagate(agent.getType("[Ljava/lang/Enum;"));
|
||||||
break;
|
break;
|
||||||
|
case "getName":
|
||||||
|
method.getResult().propagate(agent.getType("java.lang.String"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user