mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -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;
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -794,7 +794,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
}
|
||||
}
|
||||
|
||||
return new VirtualTableProvider(classes, virtualMethods);
|
||||
return new VirtualTableProvider(classes, virtualMethods, controller::isVirtual);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -226,6 +226,7 @@ public final class Platform {
|
|||
}
|
||||
|
||||
@Unmanaged
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static String getName(PlatformClass cls) {
|
||||
return cls.getMetadata().getName();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user