diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 3b312839b..000000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/core/src/main/java/org/teavm/backend/c/CTarget.java b/core/src/main/java/org/teavm/backend/c/CTarget.java
index 9d8dcf0a0..e3cd75426 100644
--- a/core/src/main/java/org/teavm/backend/c/CTarget.java
+++ b/core/src/main/java/org/teavm/backend/c/CTarget.java
@@ -36,6 +36,7 @@ import java.util.stream.Collectors;
import org.teavm.ast.InvocationExpr;
import org.teavm.ast.decompilation.Decompiler;
import org.teavm.backend.c.analyze.CDependencyListener;
+import org.teavm.backend.c.analyze.InteropDependencyListener;
import org.teavm.backend.c.generate.BufferedCodeWriter;
import org.teavm.backend.c.generate.ClassGenerator;
import org.teavm.backend.c.generate.CodeGenerationVisitor;
@@ -148,7 +149,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
@Override
public List getDependencyListeners() {
- return Arrays.asList(new CDependencyListener(), exportDependencyListener);
+ return Arrays.asList(new CDependencyListener(), exportDependencyListener, new InteropDependencyListener());
}
@Override
diff --git a/core/src/main/java/org/teavm/backend/c/analyze/InteropDependencyListener.java b/core/src/main/java/org/teavm/backend/c/analyze/InteropDependencyListener.java
new file mode 100644
index 000000000..d24dee91f
--- /dev/null
+++ b/core/src/main/java/org/teavm/backend/c/analyze/InteropDependencyListener.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.backend.c.analyze;
+
+import org.teavm.dependency.AbstractDependencyListener;
+import org.teavm.dependency.DependencyAgent;
+import org.teavm.dependency.MethodDependency;
+import org.teavm.interop.Import;
+import org.teavm.interop.Structure;
+import org.teavm.model.AnnotationReader;
+import org.teavm.model.ClassReader;
+import org.teavm.model.ElementModifier;
+import org.teavm.model.FieldReader;
+
+public class InteropDependencyListener extends AbstractDependencyListener {
+ @Override
+ public void classReached(DependencyAgent agent, String className) {
+ if (agent.getClassHierarchy().isSuperType(Structure.class.getName(), className, false)) {
+ ClassReader cls = agent.getClassSource().get(className);
+ if (cls != null) {
+ for (FieldReader field : cls.getFields()) {
+ if (!field.hasModifier(ElementModifier.STATIC)) {
+ agent.linkField(field.getReference());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void methodReached(DependencyAgent agent, MethodDependency method) {
+ if (method.isMissing() || !method.getMethod().hasModifier(ElementModifier.NATIVE)) {
+ return;
+ }
+
+ AnnotationReader importAnnot = method.getMethod().getAnnotations().get(Import.class.getName());
+ if (importAnnot == null) {
+ return;
+ }
+
+ if (method.getReference().getReturnType().isObject("java.lang.String")) {
+ method.getResult().propagate(agent.getType("java.lang.String"));
+ }
+ }
+}
diff --git a/core/src/main/java/org/teavm/backend/lowlevel/transform/CoroutineTransformation.java b/core/src/main/java/org/teavm/backend/lowlevel/transform/CoroutineTransformation.java
index 84255f83d..540fc00b8 100644
--- a/core/src/main/java/org/teavm/backend/lowlevel/transform/CoroutineTransformation.java
+++ b/core/src/main/java/org/teavm/backend/lowlevel/transform/CoroutineTransformation.java
@@ -37,7 +37,6 @@ import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;
import org.teavm.model.Program;
import org.teavm.model.TextLocation;
-import org.teavm.model.TryCatchBlock;
import org.teavm.model.ValueType;
import org.teavm.model.Variable;
import org.teavm.model.instructions.BranchingCondition;
@@ -61,13 +60,15 @@ import org.teavm.model.util.DefinitionExtractor;
import org.teavm.model.util.LivenessAnalyzer;
import org.teavm.model.util.PhiUpdater;
import org.teavm.model.util.ProgramUtils;
-import org.teavm.model.util.TransitionExtractor;
import org.teavm.model.util.TypeInferer;
import org.teavm.model.util.UsageExtractor;
import org.teavm.model.util.VariableType;
import org.teavm.runtime.Fiber;
public class CoroutineTransformation {
+ private static final MethodReference FIBER_SUSPEND = new MethodReference(Fiber.class, "suspend",
+ Fiber.AsyncCall.class, Object.class);
+ private static final String ASYNC_CALL = Fiber.class.getName() + "$AsyncCall";
private ClassReaderSource classSource;
private LivenessAnalyzer livenessAnalysis = new LivenessAnalyzer();
private TypeInferer variableTypes = new TypeInferer();
@@ -89,6 +90,11 @@ public class CoroutineTransformation {
return;
}
+ ClassReader cls = classSource.get(methodReference.getClassName());
+ if (cls != null && cls.getInterfaces().contains(ASYNC_CALL)) {
+ return;
+ }
+
boolean hasJob = false;
for (BasicBlock block : program.getBasicBlocks()) {
if (hasSplitInstructions(block)) {
@@ -176,15 +182,7 @@ public class CoroutineTransformation {
return Collections.emptyMap();
}
- BitSet live = new BitSet();
- TransitionExtractor transitionExtractor = new TransitionExtractor();
- block.getLastInstruction().acceptVisitor(transitionExtractor);
- for (BasicBlock successor : transitionExtractor.getTargets()) {
- live.or(livenessAnalysis.liveIn(successor.getIndex()));
- }
- for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
- live.or(livenessAnalysis.liveIn(tryCatch.getHandler().getIndex()));
- }
+ BitSet live = livenessAnalysis.liveOut(block.getIndex());
Map result = new LinkedHashMap<>();
UsageExtractor use = new UsageExtractor();
@@ -224,6 +222,9 @@ public class CoroutineTransformation {
if (instruction instanceof InvokeInstruction) {
InvokeInstruction invoke = (InvokeInstruction) instruction;
MethodReference method = findRealMethod(invoke.getMethod());
+ if (method.equals(FIBER_SUSPEND)) {
+ return true;
+ }
if (method.getClassName().equals(Fiber.class.getName())) {
return false;
}
diff --git a/core/src/main/java/org/teavm/model/analysis/EscapeAnalysis.java b/core/src/main/java/org/teavm/model/analysis/EscapeAnalysis.java
index d64c5bb48..b5471993c 100644
--- a/core/src/main/java/org/teavm/model/analysis/EscapeAnalysis.java
+++ b/core/src/main/java/org/teavm/model/analysis/EscapeAnalysis.java
@@ -39,7 +39,6 @@ import org.teavm.model.Instruction;
import org.teavm.model.MethodReference;
import org.teavm.model.Phi;
import org.teavm.model.Program;
-import org.teavm.model.TryCatchBlock;
import org.teavm.model.ValueType;
import org.teavm.model.Variable;
import org.teavm.model.instructions.AbstractInstructionVisitor;
@@ -65,7 +64,6 @@ import org.teavm.model.instructions.StringConstantInstruction;
import org.teavm.model.instructions.UnwrapArrayInstruction;
import org.teavm.model.util.DefinitionExtractor;
import org.teavm.model.util.LivenessAnalyzer;
-import org.teavm.model.util.TransitionExtractor;
import org.teavm.model.util.UsageExtractor;
public class EscapeAnalysis {
@@ -189,17 +187,7 @@ public class EscapeAnalysis {
}
private BitSet getUsedVarsInBlock(LivenessAnalyzer liveness, BasicBlock block) {
- BitSet usedVars = new BitSet();
- TransitionExtractor transitionExtractor = new TransitionExtractor();
- block.getLastInstruction().acceptVisitor(transitionExtractor);
- for (BasicBlock successor : transitionExtractor.getTargets()) {
- usedVars.or(liveness.liveIn(successor.getIndex()));
- }
- for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
- usedVars.or(liveness.liveIn(tryCatch.getHandler().getIndex()));
- }
-
- return usedVars;
+ return liveness.liveOut(block.getIndex());
}
private void propagateFields(Program program, List> fields) {
diff --git a/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java b/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java
index b548f67fe..e1f434fba 100644
--- a/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java
+++ b/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java
@@ -72,8 +72,8 @@ public class GCShadowStackContributor {
public int contribute(Program program, MethodReader method) {
List