mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
First working prototype of new async
This commit is contained in:
parent
56c5fefae4
commit
8fe3876641
|
@ -91,6 +91,13 @@ public class TObject {
|
|||
|
||||
static void monitorEnterWait(final TObject o, final int count, final AsyncCallback<Void> callback) {
|
||||
final TThread thread = TThread.currentThread();
|
||||
if (o.monitor == null) {
|
||||
o.monitor = new Monitor();
|
||||
TThread.setCurrentThread(thread);
|
||||
o.monitor.count += count;
|
||||
callback.complete(null);
|
||||
return;
|
||||
}
|
||||
o.monitor.enteringThreads.add(new PlatformRunnable() {
|
||||
@Override public void run() {
|
||||
TThread.setCurrentThread(thread);
|
||||
|
@ -118,7 +125,7 @@ public class TObject {
|
|||
|
||||
o.monitor.owner = null;
|
||||
if (!o.monitor.enteringThreads.isEmpty()) {
|
||||
Platform.startThread(new PlatformRunnable() {
|
||||
Platform.postpone(new PlatformRunnable() {
|
||||
@Override public void run() {
|
||||
if (o.isEmptyMonitor() || o.monitor.owner != null) {
|
||||
return;
|
||||
|
@ -127,7 +134,7 @@ public class TObject {
|
|||
o.monitor.enteringThreads.remove().run();
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
} else {
|
||||
o.isEmptyMonitor();
|
||||
}
|
||||
|
@ -203,7 +210,7 @@ public class TObject {
|
|||
while (!listeners.isEmpty()) {
|
||||
NotifyListener listener = listeners.remove();
|
||||
if (!listener.expired()) {
|
||||
Platform.startThread(listener, false);
|
||||
Platform.postpone(listener);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +226,7 @@ public class TObject {
|
|||
while (!listeners.isEmpty()) {
|
||||
NotifyListener listener = listeners.remove();
|
||||
if (!listener.expired()) {
|
||||
Platform.startThread(listener, false);
|
||||
Platform.postpone(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +286,7 @@ public class TObject {
|
|||
@Override
|
||||
public void onTimer() {
|
||||
if (!expired()) {
|
||||
Platform.startThread(this, false);
|
||||
Platform.postpone(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,14 +71,14 @@ public class TThread extends TObject implements TRunnable {
|
|||
setCurrentThread(mainThread);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
static void setCurrentThread(TThread thread) {
|
||||
if (currentThread != thread) {
|
||||
currentThread = thread;
|
||||
currentThread.timeSliceStart = System.currentTimeMillis();
|
||||
}
|
||||
currentThread.timeSliceStart = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
static TThread getMainThread(){
|
||||
|
@ -102,24 +102,20 @@ public class TThread extends TObject implements TRunnable {
|
|||
|
||||
public static void yield() {
|
||||
if (currentThread.timeSliceStart + 100 < System.currentTimeMillis()) {
|
||||
switchContext();
|
||||
switchContext(currentThread);
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
static native void switchContext();
|
||||
static native void switchContext(TThread thread);
|
||||
|
||||
private static void switchContext(final AsyncCallback<Void> callback) {
|
||||
final TThread thread = currentThread();
|
||||
Platform.startThread(new PlatformRunnable() {
|
||||
private static void switchContext(final TThread thread, final AsyncCallback<Void> callback) {
|
||||
Platform.postpone(new PlatformRunnable() {
|
||||
@Override public void run() {
|
||||
setCurrentThread(thread);
|
||||
callback.complete(null);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
private static void yieldImpl() {
|
||||
});
|
||||
}
|
||||
|
||||
public void interrupt() {
|
||||
|
|
|
@ -204,7 +204,8 @@ public class Decompiler {
|
|||
AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods);
|
||||
splitter.split(method.getProgram());
|
||||
for (int i = 0; i < splitter.size(); ++i) {
|
||||
AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i));
|
||||
AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i),
|
||||
i > 0);
|
||||
node.getBody().add(part);
|
||||
}
|
||||
Program program = method.getProgram();
|
||||
|
@ -227,7 +228,7 @@ public class Decompiler {
|
|||
Program program = method.getProgram();
|
||||
int[] targetBlocks = new int[program.basicBlockCount()];
|
||||
Arrays.fill(targetBlocks, -1);
|
||||
methodNode.setBody(getRegularMethodStatement(program, targetBlocks).getStatement());
|
||||
methodNode.setBody(getRegularMethodStatement(program, targetBlocks, false).getStatement());
|
||||
for (int i = 0; i < program.variableCount(); ++i) {
|
||||
methodNode.getVariables().add(program.variableAt(i).getRegister());
|
||||
}
|
||||
|
@ -242,7 +243,7 @@ public class Decompiler {
|
|||
return methodNode;
|
||||
}
|
||||
|
||||
private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks) {
|
||||
private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks, boolean async) {
|
||||
AsyncMethodPart result = new AsyncMethodPart();
|
||||
lastBlockId = 1;
|
||||
graph = ProgramUtils.buildControlFlowGraph(program);
|
||||
|
@ -290,6 +291,7 @@ public class Decompiler {
|
|||
if (head != -1 && loopSuccessors[head] == next) {
|
||||
next = head;
|
||||
}
|
||||
boolean saved = !async;
|
||||
if (node >= 0) {
|
||||
generator.currentBlock = program.basicBlockAt(node);
|
||||
int tmp = indexer.nodeAt(next);
|
||||
|
@ -308,8 +310,9 @@ public class Decompiler {
|
|||
generator.setCurrentLocation(nodeLocation);
|
||||
}
|
||||
insn.acceptVisitor(generator);
|
||||
if (j == 0 && insn instanceof InvokeInstruction) {
|
||||
if (insn instanceof InvokeInstruction && !saved) {
|
||||
generator.statements.add(new SaveStatement());
|
||||
saved = true;
|
||||
}
|
||||
}
|
||||
if (targetBlocks[node] >= 0) {
|
||||
|
|
|
@ -711,7 +711,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.append("var $T").ws().append('=').ws().append("$rt_nativeThread();").softNewLine();
|
||||
writer.append("$ptr").ws().append('=').ws().append("$T.pop();");
|
||||
for (int i = variableCount - 1; i > ref.parameterCount(); --i) {
|
||||
writer.append(variableName(i)).ws().append('=').ws().append("T.pop();");
|
||||
writer.append(variableName(i)).ws().append('=').ws().append("$T.pop();");
|
||||
}
|
||||
writer.softNewLine();
|
||||
writer.outdent().append("}").softNewLine();
|
||||
|
@ -724,6 +724,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
part.getStatement().acceptVisitor(Renderer.this);
|
||||
writer.outdent();
|
||||
}
|
||||
writer.append("default:").ws().append("throw new Error('Invalid recorded state');").softNewLine();
|
||||
writer.append("}").softNewLine();
|
||||
writer.outdent().append("}").softNewLine();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -444,17 +444,17 @@ function TeaVMThread(runner) {
|
|||
this.attribute = null;
|
||||
}
|
||||
TeaVMThread.prototype.push = function(value) {
|
||||
this.stack.push[value];
|
||||
this.stack.push(value);
|
||||
return this;
|
||||
}
|
||||
TeaVMThread.prototype.pop = function() {
|
||||
return this.stack.pop();
|
||||
}
|
||||
TeaVMThread.prototype.isResuming = function() {
|
||||
return this.status == 1;
|
||||
return this.status == 2;
|
||||
}
|
||||
TeaVMThread.prototype.isSuspending = function() {
|
||||
return this.status == 2;
|
||||
return this.status == 1;
|
||||
}
|
||||
TeaVMThread.prototype.suspend = function(callback) {
|
||||
this.suspendCallback = callback;
|
||||
|
@ -489,10 +489,12 @@ TeaVMThread.prototype.run = function() {
|
|||
}
|
||||
}
|
||||
function $rt_suspending() {
|
||||
return $rt_nativeThread().isSuspending();
|
||||
var thread = $rt_nativeThread();
|
||||
return thread != null && thread.isSuspending();
|
||||
}
|
||||
function $rt_resuming() {
|
||||
return $rt_nativeThread().isResuming();
|
||||
var thread = $rt_nativeThread();
|
||||
return thread != null && thread.isResuming();
|
||||
}
|
||||
function $rt_suspend(callback) {
|
||||
return $rt_nativeThread().suspend(callback);
|
||||
|
|
|
@ -107,12 +107,16 @@ public final class Platform {
|
|||
|
||||
@GeneratedBy(PlatformGenerator.class)
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static native void startThread(PlatformRunnable runnable, boolean newNativeThread);
|
||||
public static native void startThread(PlatformRunnable runnable);
|
||||
|
||||
private static void launchThread(PlatformRunnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
public static void postpone(PlatformRunnable runnable) {
|
||||
schedule(runnable, 0);
|
||||
}
|
||||
|
||||
@GeneratedBy(PlatformGenerator.class)
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static native int schedule(PlatformRunnable runnable, int timeout);
|
||||
|
|
|
@ -40,6 +40,7 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin {
|
|||
MethodReference asyncRef = getAsyncReference(methodRef);
|
||||
writer.append("var thread").ws().append('=').ws().append("$rt_nativeThread();").softNewLine();
|
||||
writer.append("if").ws().append("(thread.isResuming())").ws().append("{").indent().softNewLine();
|
||||
writer.append("thread.status").ws().append("=").ws().append("0;").softNewLine();
|
||||
writer.append("var result").ws().append("=").ws().append("thread.attribute;").softNewLine();
|
||||
writer.append("if").ws().append("(result instanceof Error)").ws().append("{").indent().softNewLine();
|
||||
writer.append("throw result;").softNewLine();
|
||||
|
|
|
@ -153,7 +153,11 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
|
|||
PlatformRunnable.class, void.class);
|
||||
String runnable = context.getParameterName(1);
|
||||
writer.append("return window.setTimeout(function()").ws().append("{").indent().softNewLine();
|
||||
writer.append("$rt_threadStarter(").appendMethodBody(launchRef).append(")");
|
||||
if (timeout) {
|
||||
writer.appendMethodBody(launchRef);
|
||||
} else {
|
||||
writer.append("$rt_threadStarter(").appendMethodBody(launchRef).append(")");
|
||||
}
|
||||
writer.append("(").append(runnable).append(");").softNewLine();
|
||||
writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0")
|
||||
.append(");").softNewLine();
|
||||
|
|
Loading…
Reference in New Issue
Block a user