mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
Partial support of synchronized methods
This commit is contained in:
parent
a4cb94df2f
commit
98247b9927
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.dependency;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -109,6 +110,40 @@ class DependencyGraphBuilder {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (method.hasModifier(ElementModifier.SYNCHRONIZED)) {
|
||||
List<DependencyNode> syncNodes = new ArrayList<>();
|
||||
|
||||
MethodDependency methodDep = dependencyChecker.linkMethod(
|
||||
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null);
|
||||
syncNodes.add(methodDep.getVariable(1));
|
||||
methodDep.use();
|
||||
|
||||
methodDep = dependencyChecker.linkMethod(
|
||||
new MethodReference(Object.class, "monitorEnterSync", Object.class, void.class), null);
|
||||
syncNodes.add(methodDep.getVariable(1));
|
||||
methodDep.use();
|
||||
|
||||
methodDep = dependencyChecker.linkMethod(
|
||||
new MethodReference(Object.class, "monitorExit", Object.class, void.class), null);
|
||||
syncNodes.add(methodDep.getVariable(1));
|
||||
methodDep.use();
|
||||
|
||||
methodDep = dependencyChecker.linkMethod(
|
||||
new MethodReference(Object.class, "monitorExitSync", Object.class, void.class), null);
|
||||
syncNodes.add(methodDep.getVariable(1));
|
||||
methodDep.use();
|
||||
|
||||
if (method.hasModifier(ElementModifier.STATIC)) {
|
||||
for (DependencyNode node : syncNodes) {
|
||||
node.propagate(dependencyChecker.getType("java.lang.Class"));
|
||||
}
|
||||
} else {
|
||||
for (DependencyNode node : syncNodes) {
|
||||
nodes[0].connect(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ExceptionConsumer createExceptionConsumer(MethodDependency methodDep, BasicBlockReader block) {
|
||||
|
|
|
@ -383,6 +383,9 @@ public class Decompiler {
|
|||
if (modifiers.contains(ElementModifier.ENUM)) {
|
||||
result.add(NodeModifier.ENUM);
|
||||
}
|
||||
if (modifiers.contains(ElementModifier.SYNCHRONIZED)) {
|
||||
result.add(NodeModifier.SYNCHRONIZED);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -725,18 +725,43 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.softNewLine();
|
||||
writer.outdent().append("}").softNewLine();
|
||||
|
||||
if (methodNode.getModifiers().contains(NodeModifier.SYNCHRONIZED)) {
|
||||
writer.append("try").ws().append('{').indent().softNewLine();
|
||||
}
|
||||
writer.append(mainLoopName()).append(":").ws().append("while").ws().append("(true)")
|
||||
.ws().append("{").ws();
|
||||
writer.append("switch").ws().append("(").append(pointerName()).append(")").ws()
|
||||
.append('{').softNewLine();
|
||||
for (int i = 0; i < methodNode.getBody().size(); ++i) {
|
||||
writer.append("case ").append(i).append(":").indent().softNewLine();
|
||||
if (i == 0 && methodNode.getModifiers().contains(NodeModifier.SYNCHRONIZED)) {
|
||||
writer.appendMethodBody(new MethodReference(Object.class, "monitorEnter",
|
||||
Object.class, void.class));
|
||||
writer.append("(");
|
||||
appendMonitor(methodNode);
|
||||
writer.append(");").softNewLine();
|
||||
emitSuspendChecker();
|
||||
}
|
||||
AsyncMethodPart part = methodNode.getBody().get(i);
|
||||
part.getStatement().acceptVisitor(Renderer.this);
|
||||
writer.outdent();
|
||||
}
|
||||
writer.append("default:").ws().appendFunction("$rt_invalidPointer").append("();").softNewLine();
|
||||
writer.append("}}").softNewLine();
|
||||
|
||||
if (methodNode.getModifiers().contains(NodeModifier.SYNCHRONIZED)) {
|
||||
writer.outdent().append("}").ws().append("finally").ws().append('{').indent().softNewLine();
|
||||
writer.append("if").ws().append("(!").appendFunction("$rt_suspending").append("())")
|
||||
.ws().append("{").indent().softNewLine();
|
||||
writer.appendMethodBody(new MethodReference(Object.class, "monitorExit",
|
||||
Object.class, void.class));
|
||||
writer.append("(");
|
||||
appendMonitor(methodNode);
|
||||
writer.append(");").softNewLine();
|
||||
writer.outdent().append('}').softNewLine();
|
||||
writer.outdent().append('}').softNewLine();
|
||||
}
|
||||
|
||||
writer.appendFunction("$rt_nativeThread").append("().").append(pushName).append("(");
|
||||
for (int i = firstToSave; i < variableCount; ++i) {
|
||||
writer.append(variableName(i)).append(',').ws();
|
||||
|
@ -794,6 +819,15 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
}
|
||||
|
||||
private void appendMonitor(MethodNode methodNode) throws IOException {
|
||||
if (methodNode.getModifiers().contains(NodeModifier.STATIC)) {
|
||||
writer.appendFunction("$rt_cls").append("(")
|
||||
.appendClass(methodNode.getReference().getClassName()).append(")");
|
||||
} else {
|
||||
writer.append(variableName(0));
|
||||
}
|
||||
}
|
||||
|
||||
private void pushLocation(NodeLocation location) {
|
||||
LocationStackEntry prevEntry = locationStack.peek();
|
||||
if (location != null) {
|
||||
|
|
|
@ -22,5 +22,6 @@ package org.teavm.javascript.ast;
|
|||
public enum NodeModifier {
|
||||
STATIC,
|
||||
INTERFACE,
|
||||
ENUM
|
||||
ENUM,
|
||||
SYNCHRONIZED
|
||||
}
|
||||
|
|
|
@ -72,6 +72,10 @@ public class AsyncMethodFinder {
|
|||
if (asyncMethods.contains(method.getReference()) || method.getProgram() == null) {
|
||||
continue;
|
||||
}
|
||||
if (method.hasModifier(ElementModifier.SYNCHRONIZED)) {
|
||||
add(method.getReference());
|
||||
continue;
|
||||
}
|
||||
ProgramReader program = method.getProgram();
|
||||
AsyncInstructionReader insnReader = new AsyncInstructionReader();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user