implement corouting.wrap(), fix bugs in coroutine.status(), fix StackState.insert()

This commit is contained in:
James Roseborough
2007-10-22 21:05:04 +00:00
parent 78eaaf0fa0
commit 8248cca2bf
5 changed files with 128 additions and 51 deletions

View File

@@ -7,20 +7,22 @@ import lua.io.Closure;
public class LThread extends LValue {
private static final int STATUS_SUSPENDED = 1;
private static final int STATUS_SUSPENDED = 0;
private static final int STATUS_RUNNING = 1;
private static final int STATUS_NORMAL = 2;
private static final int STATUS_ACTIVE = 3;
private static final int STATUS_DEAD = 4;
private static final int STATUS_DEAD = 3;
private static final String[] NAMES = {
"suspended",
"running",
"normal",
"active",
"dead" };
private int status = STATUS_SUSPENDED;
private StackState threadVm;
private static LThread running;
public LThread(Closure c) {
// TODO: inherit globals!
@@ -40,37 +42,45 @@ public class LThread extends LValue {
return NAMES[status];
}
/** This needs to leave any values returned by yield in the corouting
public static LThread getRunning() {
return running;
}
/** This needs to leave any values returned by yield in the coroutine
* on the calling vm stack
* @param vm
* @param prior
* @param nargs
*/
public void resumeFrom(VM vm, LThread prior) {
public void resumeFrom(VM vm, int nargs) {
if ( status == STATUS_DEAD ) {
vm.settop(0);
vm.pushboolean(false);
vm.pushstring("cannot resume dead coroutine");
vm.error("cannot resume dead coroutine");
// vm.settop(0);
// vm.pushboolean(false);
// vm.pushstring("cannot resume dead coroutine");
return;
}
// set prior thread to normal status while we are running
if ( prior != null )
prior.status = STATUS_NORMAL;
try {
// set prior thread to normal status while t
LThread prior = running;
try {
// set our status to running
running = this;
if ( prior != null )
prior.status = STATUS_NORMAL;
status = STATUS_RUNNING;
// copy args in
if ( threadVm.cc < 0 ) {
vm.xmove(threadVm, vm.gettop() - 2);
vm.xmove(threadVm, nargs);
threadVm.prepStackCall();
} else {
threadVm.settop(0);
vm.xmove(threadVm, vm.gettop() - 2);
vm.xmove(threadVm, nargs);
}
// run this vm until it yields
status = STATUS_ACTIVE;
while ( threadVm.cc >= 0 && status == STATUS_ACTIVE )
while ( threadVm.cc >= 0 && status == STATUS_RUNNING )
threadVm.exec();
// copy return values from yielding stack state
@@ -90,18 +100,21 @@ public class LThread extends LValue {
vm.pushstring("thread: "+t);
} finally {
// previous thread is now running
running = prior;
if ( running != null )
running.status = STATUS_RUNNING;
// check if thread is actually dead
if ( threadVm.cc < 0 )
status = STATUS_DEAD;
// reset prior thread status
if ( prior != null )
prior.status = STATUS_ACTIVE;
}
}
public boolean yield() {
if ( status == STATUS_ACTIVE )
if ( status == STATUS_RUNNING )
status = STATUS_SUSPENDED;
return true;
}