mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Most of the elements are in place for monitors to work... something is wrong tough because I get errors when I try to compile files with synchronized sections.
This commit is contained in:
parent
cca4336a15
commit
2fbc50e76f
|
@ -29,6 +29,39 @@ import org.teavm.runtime.Async;
|
|||
*/
|
||||
@Superclass("")
|
||||
public class TObject {
|
||||
|
||||
private TThread owner;
|
||||
private TObject monitorLock;
|
||||
private int monitorCount=0;
|
||||
|
||||
static void monitorEnter(TObject o){
|
||||
if ( o.monitorLock == null ){
|
||||
o.monitorLock = new TObject();
|
||||
}
|
||||
while (o.owner != null && o.owner != TThread.currentThread() ){
|
||||
try {
|
||||
o.monitorLock.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
o.owner = TThread.currentThread();
|
||||
o.monitorCount++;
|
||||
|
||||
}
|
||||
|
||||
static void monitorExit(TObject o){
|
||||
o.owner = null;
|
||||
o.monitorCount--;
|
||||
if ( o.monitorLock != null ){
|
||||
o.monitorLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
static boolean holdsLock(TObject o){
|
||||
return o.owner == TThread.currentThread();
|
||||
}
|
||||
|
||||
@Rename("fakeInit")
|
||||
public TObject() {
|
||||
}
|
||||
|
|
|
@ -112,8 +112,8 @@ public class TThread extends TObject implements TRunnable {
|
|||
return id;
|
||||
}
|
||||
|
||||
public static boolean holdsLock(@SuppressWarnings("unused") TObject obj) {
|
||||
return true;
|
||||
public static boolean holdsLock(TObject obj) {
|
||||
return TObject.holdsLock(obj);
|
||||
}
|
||||
|
||||
public static void sleep(long millis) throws TInterruptedException {
|
||||
|
@ -123,4 +123,6 @@ public class TThread extends TObject implements TRunnable {
|
|||
@Async
|
||||
@GeneratedBy(ThreadNativeGenerator.class)
|
||||
private static native void sleep(double millis) throws TInterruptedException;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -508,6 +508,16 @@ public class AstIO {
|
|||
throw new IOExceptionWrapper(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private NodeLocation readLocation(DataInput input) throws IOException {
|
||||
|
|
|
@ -261,6 +261,16 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class Item {
|
||||
|
|
|
@ -116,4 +116,14 @@ class BreakToContinueReplacer implements StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,4 +111,14 @@ class CertainBlockCountVisitor implements StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -618,4 +618,14 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
public void visit(RestoreAsyncStatement statement) {
|
||||
resultStmt = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
resultStmt = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
resultStmt = statement;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,4 +121,14 @@ class RedundantLabelEliminator implements StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,4 +115,14 @@ class ReferenceCountingVisitor implements StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,40 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
private DeferredCallSite prevCallSite;
|
||||
private boolean async;
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
if (async){
|
||||
try {
|
||||
MethodReference monitorEnterRef = new MethodReference(
|
||||
Object.class, "monitorEnter", Object.class, void.class);
|
||||
|
||||
writer.appendMethodBody(monitorEnterRef).append("(");
|
||||
statement.acceptVisitor(this);
|
||||
writer.append(");").softNewLine();
|
||||
|
||||
} catch (IOException ex){
|
||||
throw new RenderingException("IO error occured", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
if (async){
|
||||
try {
|
||||
MethodReference monitorExitRef = new MethodReference(
|
||||
Object.class, "monitorExit", Object.class, void.class);
|
||||
|
||||
writer.appendMethodBody(monitorExitRef).append("(");
|
||||
statement.acceptVisitor(this);
|
||||
writer.append(");").softNewLine();
|
||||
} catch (IOException ex){
|
||||
throw new RenderingException("IO error occured", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class InjectorHolder {
|
||||
public final Injector injector;
|
||||
|
||||
|
|
|
@ -670,10 +670,24 @@ class StatementGenerator implements InstructionVisitor {
|
|||
@Override
|
||||
public void visit(MonitorEnterInstruction insn) {
|
||||
|
||||
MonitorEnterStatement stmt = new MonitorEnterStatement();
|
||||
stmt.setLocation(currentLocation);
|
||||
|
||||
VariableExpr expr = new VariableExpr();
|
||||
expr.setIndex(insn.getObjectRef().getIndex());
|
||||
expr.setLocation(currentLocation);
|
||||
stmt.setObjectRef(expr);
|
||||
statements.add(stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitInstruction insn) {
|
||||
|
||||
MonitorExitStatement stmt = new MonitorExitStatement();
|
||||
stmt.setLocation(currentLocation);
|
||||
VariableExpr expr = new VariableExpr();
|
||||
expr.setLocation(currentLocation);
|
||||
expr.setIndex(insn.getObjectRef().getIndex());
|
||||
stmt.setObjectRef(expr);
|
||||
statements.add(stmt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,4 +114,14 @@ class TryCatchFinder implements StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,4 +228,14 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
|||
@Override
|
||||
public void visit(RestoreAsyncStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2015 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.javascript.ast;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author shannah
|
||||
*/
|
||||
public class MonitorEnterStatement extends Statement {
|
||||
|
||||
private NodeLocation location;
|
||||
private VariableExpr objectRef;
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the location
|
||||
*/
|
||||
public NodeLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location the location to set
|
||||
*/
|
||||
public void setLocation(NodeLocation location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the objectRef
|
||||
*/
|
||||
public VariableExpr getObjectRef() {
|
||||
return objectRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objectRef the objectRef to set
|
||||
*/
|
||||
public void setObjectRef(VariableExpr objectRef) {
|
||||
this.objectRef = objectRef;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2015 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.javascript.ast;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author shannah
|
||||
*/
|
||||
public class MonitorExitStatement extends Statement {
|
||||
|
||||
private NodeLocation location;
|
||||
private VariableExpr objectRef;
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the location
|
||||
*/
|
||||
public NodeLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location the location to set
|
||||
*/
|
||||
public void setLocation(NodeLocation location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the objectRef
|
||||
*/
|
||||
public VariableExpr getObjectRef() {
|
||||
return objectRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objectRef the objectRef to set
|
||||
*/
|
||||
public void setObjectRef(VariableExpr objectRef) {
|
||||
this.objectRef = objectRef;
|
||||
}
|
||||
|
||||
}
|
|
@ -198,4 +198,14 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor {
|
|||
statement.setReceiver(varNames[statement.getReceiver()]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorEnterStatement statement) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitStatement statement) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,4 +45,8 @@ public interface StatementVisitor {
|
|||
void visit(TryCatchStatement statement);
|
||||
|
||||
void visit(RestoreAsyncStatement statement);
|
||||
|
||||
void visit(MonitorEnterStatement statement);
|
||||
|
||||
void visit(MonitorExitStatement statement);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.model;
|
||||
|
||||
import java.util.*;
|
||||
import org.teavm.model.instructions.AssignInstruction;
|
||||
import org.teavm.model.instructions.InstructionReader;
|
||||
|
||||
/**
|
||||
|
@ -66,7 +67,19 @@ public class BasicBlock implements BasicBlockReader {
|
|||
@Override
|
||||
public void add(int index, Instruction e) {
|
||||
if (e.getBasicBlock() != null) {
|
||||
throw new IllegalArgumentException("This instruction is in some basic block");
|
||||
if (e instanceof AssignInstruction){
|
||||
AssignInstruction ae = (AssignInstruction)e;
|
||||
System.out.println("Assignment "+ae.getReceiver()+" -> "+ae.getAssignee());
|
||||
System.out.println(ae.getReceiver().getDebugNames());
|
||||
System.out.println(ae.getReceiver().getIndex());
|
||||
System.out.println(ae.getReceiver().getProgram());
|
||||
System.out.println(ae.getAssignee().getDebugNames());
|
||||
System.out.println(ae.getAssignee().getIndex());
|
||||
System.out.println(ae.getAssignee().getProgram());
|
||||
|
||||
System.out.println(ae.getBasicBlock().getInstructions());
|
||||
}
|
||||
throw new IllegalArgumentException("This instruction is in some basic block "+e+", "+e.getLocation());
|
||||
}
|
||||
e.setBasicBlock(BasicBlock.this);
|
||||
instructions.add(index, e);
|
||||
|
|
|
@ -231,12 +231,12 @@ public abstract class InstructionVariableMapper implements InstructionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(MonitorEnterInstruction insn) {
|
||||
|
||||
insn.setObjectRef(map(insn.getObjectRef()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitInstruction insn) {
|
||||
|
||||
insn.setObjectRef(map(insn.getObjectRef()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -421,12 +421,14 @@ public class GlobalValueNumbering implements MethodOptimization {
|
|||
|
||||
@Override
|
||||
public void visit(MonitorEnterInstruction insn) {
|
||||
|
||||
int val = map[insn.getObjectRef().getIndex()];
|
||||
insn.setObjectRef(program.variableAt(val));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitInstruction insn) {
|
||||
|
||||
int val = map[insn.getObjectRef().getIndex()];
|
||||
insn.setObjectRef(program.variableAt(val));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1556,10 +1556,19 @@ public class ProgramParser implements VariableDebugInformation {
|
|||
nextIndexes = new int[0];
|
||||
return;
|
||||
}
|
||||
case Opcodes.MONITORENTER:
|
||||
case Opcodes.MONITOREXIT:
|
||||
popSingle();
|
||||
case Opcodes.MONITORENTER: {
|
||||
MonitorEnterInstruction insn = new MonitorEnterInstruction();
|
||||
insn.setObjectRef(getVariable(popSingle()));
|
||||
addInstruction(insn);
|
||||
break;
|
||||
}
|
||||
case Opcodes.MONITOREXIT: {
|
||||
MonitorExitInstruction insn = new MonitorExitInstruction();
|
||||
insn.setObjectRef(getVariable(popSingle()));
|
||||
addInstruction(insn);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -450,12 +450,12 @@ public class SSATransformer {
|
|||
|
||||
@Override
|
||||
public void visit(MonitorEnterInstruction insn) {
|
||||
|
||||
insn.setObjectRef(use(insn.getObjectRef()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MonitorExitInstruction insn) {
|
||||
|
||||
insn.setObjectRef(use(insn.getObjectRef()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
19
teavm-samples/teavm-samples-async/nb-configuration.xml
Normal file
19
teavm-samples/teavm-samples-async/nb-configuration.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<ca-weblite-netbeans-mirah.project_5f_type>maven</ca-weblite-netbeans-mirah.project_5f_type>
|
||||
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>gfv3ee6</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
17
teavm-samples/teavm-samples-async/nbactions.xml
Normal file
17
teavm-samples/teavm-samples-async/nbactions.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<actionName>build</actionName>
|
||||
<packagings>
|
||||
<packaging>*</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<skipTests>true</skipTests>
|
||||
<jpda.listen>maven</jpda.listen>
|
||||
|
||||
</properties>
|
||||
</action>
|
||||
</actions>
|
|
@ -48,6 +48,20 @@ public final class AsyncProgram {
|
|||
|
||||
}, "Test Thread");
|
||||
t.start();
|
||||
|
||||
Thread t2 = new Thread(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
doRun(lock);
|
||||
} catch (InterruptedException ex){
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}, "Test Thread 2");
|
||||
t2.start();
|
||||
System.out.println("Should be main -> Current thread is "+Thread.currentThread().getName());
|
||||
System.out.println("Now trying wait...");
|
||||
|
||||
|
@ -68,6 +82,12 @@ public final class AsyncProgram {
|
|||
Thread.sleep(5000);
|
||||
System.out.println("Current thread is "+Thread.currentThread().getName());
|
||||
System.out.println("Finished another 5 second sleep");
|
||||
|
||||
synchronized(lock){
|
||||
System.out.println("Inside locked section of thread "+Thread.currentThread().getName());
|
||||
Thread.sleep(2000);
|
||||
System.out.println("Finished locked section of thread "+Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void withoutAsync() {
|
||||
|
@ -113,4 +133,6 @@ public final class AsyncProgram {
|
|||
System.out.println("Thread.yield called");
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user