C: fix duplicate call of some <clinit> methods when using reflection

This commit is contained in:
Alexey Andreev 2019-08-29 14:33:23 +03:00
parent 5a8284222a
commit 6b0b30cb23
3 changed files with 17 additions and 5 deletions

View File

@ -366,7 +366,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
boolean vmAssertions = Boolean.parseBoolean(System.getProperty("teavm.c.vmAssertions", "false"));
GenerationContext context = new GenerationContext(vtableProvider, characteristics,
controller.getDependencyInfo(), stringPool, nameProvider, controller.getDiagnostics(), classes,
intrinsics, generators, asyncMethods::contains, buildTarget, incremental, longjmpUsed,
intrinsics, generators, asyncMethods::contains, buildTarget,
controller.getClassInitializerInfo(), incremental, longjmpUsed,
vmAssertions, vmAssertions || heapDump);
BufferedCodeWriter runtimeWriter = new BufferedCodeWriter(false);
@ -752,7 +753,9 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
}
writer.println("teavm_afterInitClasses();");
generateStaticInitializerCalls(context, writer, includes, classes);
writer.println(context.getNames().forClassInitializer("java.lang.String") + "();");
if (context.getClassInitializerInfo().isDynamicInitializer("java.lang.String")) {
writer.println(context.getNames().forClassInitializer("java.lang.String") + "();");
}
generateFiberStart(context, writer, includes);
writer.outdent().println("}");

View File

@ -976,7 +976,8 @@ public class ClassGenerator {
private boolean needsInitializer(ClassReader cls) {
return !context.getCharacteristics().isStaticInit(cls.getName())
&& !context.getCharacteristics().isStructure(cls.getName())
&& cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null;
&& cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null
&& context.getClassInitializerInfo().isDynamicInitializer(cls.getName());
}
private boolean tryDelegateToMethod(ClassHolder cls, MethodHolder method) {

View File

@ -26,6 +26,7 @@ import org.teavm.dependency.DependencyInfo;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference;
import org.teavm.model.analysis.ClassInitializerInfo;
import org.teavm.model.classes.VirtualTableProvider;
import org.teavm.model.lowlevel.Characteristics;
import org.teavm.vm.BuildTarget;
@ -43,6 +44,7 @@ public class GenerationContext {
private Map<MethodReference, Intrinsic> intrinsicCache = new HashMap<>();
private Predicate<MethodReference> asyncMethods;
private BuildTarget buildTarget;
private ClassInitializerInfo classInitializerInfo;
private boolean incremental;
private boolean longjmp;
private boolean vmAssertions;
@ -51,8 +53,9 @@ public class GenerationContext {
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
DependencyInfo dependencies, StringPool stringPool, NameProvider names, Diagnostics diagnostics,
ClassReaderSource classSource, List<Intrinsic> intrinsics, List<Generator> generators,
Predicate<MethodReference> asyncMethods, BuildTarget buildTarget, boolean incremental,
boolean longjmp, boolean vmAssertions, boolean heapDump) {
Predicate<MethodReference> asyncMethods, BuildTarget buildTarget,
ClassInitializerInfo classInitializerInfo, boolean incremental, boolean longjmp, boolean vmAssertions,
boolean heapDump) {
this.virtualTableProvider = virtualTableProvider;
this.characteristics = characteristics;
this.dependencies = dependencies;
@ -64,6 +67,7 @@ public class GenerationContext {
this.generators = new ArrayList<>(generators);
this.asyncMethods = asyncMethods;
this.buildTarget = buildTarget;
this.classInitializerInfo = classInitializerInfo;
this.incremental = incremental;
this.longjmp = longjmp;
this.vmAssertions = vmAssertions;
@ -128,6 +132,10 @@ public class GenerationContext {
return buildTarget;
}
public ClassInitializerInfo getClassInitializerInfo() {
return classInitializerInfo;
}
public boolean isIncremental() {
return incremental;
}