Fix bugs in C backend

This commit is contained in:
Alexey Andreev 2019-03-26 19:09:25 +03:00
parent 9a6da19a24
commit 0dc170dad2
7 changed files with 74 additions and 38 deletions

View File

@ -30,6 +30,7 @@ public class TThread extends TObject implements TRunnable {
private static int activeCount = 1;
private long id;
private int priority;
private boolean daemon;
private long timeSliceStart;
private int yieldCount;
private final Object finishedLock = new Object();
@ -40,6 +41,10 @@ public class TThread extends TObject implements TRunnable {
private boolean alive = true;
TRunnable target;
static {
mainThread.setDaemon(true);
}
public TThread() {
this(null, null);
}
@ -107,6 +112,14 @@ public class TThread extends TObject implements TRunnable {
return name;
}
public final boolean isDaemon() {
return daemon;
}
public final void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public final void join(long millis, int nanos) throws InterruptedException {
if (currentThread() == this) {
return;

View File

@ -28,6 +28,7 @@ import org.teavm.dependency.DependencyInfo;
import org.teavm.dependency.MethodDependencyInfo;
import org.teavm.dependency.ValueDependencyInfo;
import org.teavm.interop.NoSideEffects;
import org.teavm.interop.StaticInit;
import org.teavm.model.BasicBlockReader;
import org.teavm.model.ClassHierarchy;
import org.teavm.model.ClassReader;
@ -104,7 +105,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
ClassReader cls = classes.get(className);
if (cls == null) {
if (cls == null || cls.getAnnotations().get(StaticInit.class.getName()) != null) {
classStatuses.put(className, STATIC);
return;
}

View File

@ -69,7 +69,7 @@ public final class EventQueue {
}
}
static void stop() {
public static void stop() {
finished = true;
}

View File

@ -25,6 +25,7 @@ public class Fiber {
public static final int STATE_RUNNING = 0;
public static final int STATE_SUSPENDING = 1;
public static final int STATE_RESUMING = 2;
private static int daemonCount = 1;
private int[] intValues;
private int intTop;
@ -221,6 +222,9 @@ public class Fiber {
current = this;
runner.run();
current = former;
if (!isSuspending() && Thread.currentThread().isDaemon() && --daemonCount == 0) {
EventQueue.stop();
}
}
void resume() {

View File

@ -15,7 +15,9 @@
*/
package org.teavm.platform.plugin;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.teavm.ast.InvocationExpr;
@ -36,52 +38,32 @@ class MetadataCIntrinsic implements Intrinsic {
private CodeWriter structuresWriter;
private CodeWriter staticFieldInitWriter;
private DefaultMetadataGeneratorContext metadataContext;
private MethodReference constructorMethod;
private MethodReference targetMethod;
private MetadataGenerator generator;
private Map<MethodReference, MethodGenerator> generatorMap = new HashMap<>();
MetadataCIntrinsic(ClassReaderSource classSource, ClassLoader classLoader,
void init(ClassReaderSource classSource, ClassLoader classLoader,
ServiceRepository services, Properties properties, CodeWriter structuresWriter,
CodeWriter staticFieldInitWriter, MethodReference constructorMethod, MethodReference targetMethod,
MetadataGenerator generator) {
CodeWriter staticFieldInitWriter) {
this.structuresWriter = structuresWriter;
this.staticFieldInitWriter = staticFieldInitWriter;
metadataContext = new DefaultMetadataGeneratorContext(classSource, classLoader, properties, services);
this.constructorMethod = constructorMethod;
this.targetMethod = targetMethod;
this.generator = generator;
}
public void addGenerator(MethodReference constructor, MethodReference method, MetadataGenerator generator) {
generatorMap.put(constructor, new MethodGenerator(method, generator));
}
@Override
public boolean canHandle(MethodReference methodReference) {
return constructorMethod.equals(methodReference);
return generatorMap.containsKey(methodReference);
}
@Override
public void apply(IntrinsicContext context, InvocationExpr invocation) {
writeInitializer(context, invocation);
context.writer().print(context.names().forMethod(invocation.getMethod()));
MethodGenerator generator = generatorMap.get(invocation.getMethod());
generator.apply(context, invocation);
}
private void writeInitializer(IntrinsicContext context, InvocationExpr invocation) {
MethodReference methodReference = invocation.getMethod();
if (!writtenInitializers.add(methodReference)) {
return;
}
String variableName = context.names().forMethod(methodReference);
staticFieldInitWriter.print("static ").printType(methodReference.getReturnType()).print(" ")
.print(variableName).print(" = ");
if (generator == null) {
staticFieldInitWriter.print("NULL");
} else {
Resource resource = generator.generateMetadata(metadataContext, targetMethod);
writeValue(context, resource);
}
staticFieldInitWriter.println(";");
}
private void writeValue(IntrinsicContext context, Object value) {
void writeValue(IntrinsicContext context, Object value) {
if (value == null) {
staticFieldInitWriter.print("NULL");
} else if (value instanceof String) {
@ -269,4 +251,37 @@ class MetadataCIntrinsic implements Intrinsic {
}
return a;
}
class MethodGenerator {
private MethodReference targetMethod;
private MetadataGenerator generator;
MethodGenerator(MethodReference targetMethod, MetadataGenerator generator) {
this.targetMethod = targetMethod;
this.generator = generator;
}
public void apply(IntrinsicContext context, InvocationExpr invocation) {
writeInitializer(context, invocation);
context.writer().print(context.names().forMethod(invocation.getMethod()));
}
private void writeInitializer(IntrinsicContext context, InvocationExpr invocation) {
MethodReference methodReference = invocation.getMethod();
if (!writtenInitializers.add(methodReference)) {
return;
}
String variableName = context.names().forMethod(methodReference);
staticFieldInitWriter.print("static ").printType(methodReference.getReturnType()).print(" ")
.print(variableName).print(" = ");
if (generator == null) {
staticFieldInitWriter.print("NULL");
} else {
Resource resource = generator.generateMetadata(metadataContext, targetMethod);
writeValue(context, resource);
}
staticFieldInitWriter.println(";");
}
}
}

View File

@ -48,8 +48,8 @@ public class PlatformPlugin implements TeaVMPlugin, MetadataRegistration {
@Override
public void install(TeaVMHost host) {
host.add(metadataTransformer);
if (host.getExtension(TeaVMJavaScriptHost.class) != null) {
host.add(metadataTransformer);
host.add(new ResourceTransformer());
host.add(new ResourceAccessorTransformer(host));
host.add(new ResourceAccessorDependencyListener());
@ -101,11 +101,14 @@ public class PlatformPlugin implements TeaVMPlugin, MetadataRegistration {
TeaVMCHost cHost = host.getExtension(TeaVMCHost.class);
if (cHost != null) {
metadataGeneratorConsumers.add((constructor, method, generator) -> {
cHost.addIntrinsic(ctx -> new MetadataCIntrinsic(ctx.getClassSource(), ctx.getClassLoader(),
MetadataCIntrinsic metadataCIntrinsic = new MetadataCIntrinsic();
cHost.addIntrinsic(ctx -> {
metadataCIntrinsic.init(ctx.getClassSource(), ctx.getClassLoader(),
ctx.getServices(), ctx.getProperties(), ctx.getStructureCodeWriter(),
ctx.getStaticFieldsInitWriter(), constructor, method, generator));
ctx.getStaticFieldsInitWriter());
return metadataCIntrinsic;
});
metadataGeneratorConsumers.add(metadataCIntrinsic::addGenerator);
cHost.addIntrinsic(ctx -> new ResourceReadCIntrinsic(ctx.getClassSource()));
cHost.addIntrinsic(ctx -> new Intrinsic() {
@Override

View File

@ -20,4 +20,4 @@ link_directories(${GTK3_LIBRARY_DIRS})
add_definitions(${GTK3_CFLAGS_OTHER})
add_executable(teavm_benchmark target/generated/c/classes.c)
target_link_libraries(teavm_benchmark ${GTK3_LIBRARIES} m)
target_link_libraries(teavm_benchmark ${GTK3_LIBRARIES} m rt)