mirror of
https://github.com/ParkerTenBroeck/coroutines.git
synced 2026-06-06 21:00:35 -04:00
fixed bug with saving stack
This commit is contained in:
parent
989c807aac
commit
90bfb8a631
5 changed files with 59 additions and 13 deletions
|
|
@ -2,6 +2,7 @@ import async_example.Delay;
|
||||||
import async_example.Jokio;
|
import async_example.Jokio;
|
||||||
import async_example.Socket;
|
import async_example.Socket;
|
||||||
import generator.future.Future;
|
import generator.future.Future;
|
||||||
|
import generator.future.Waker;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
|
@ -75,13 +76,17 @@ public class Examples {
|
||||||
return Future.ret(number+"ms");
|
return Future.ret(number+"ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> awaitTest(int number){
|
|
||||||
var result = awaitTest2(number).await();
|
|
||||||
var rt = Jokio.runtime().await();
|
|
||||||
rt.spawn(awaitTest2(5000));
|
|
||||||
|
|
||||||
closing(5000).await();
|
public Future<Integer> number(int value){
|
||||||
return Future.ret("Result: " + result);
|
Waker.waker().wake();
|
||||||
|
Future.yield();
|
||||||
|
return Future.ret(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<String> awaitTest(int number){
|
||||||
|
var result = number(10).await()+number(20).await();
|
||||||
|
Jokio.runtime().await().spawn(awaitTest2(5000));
|
||||||
|
return Future.ret(""+result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> closing(int number){
|
public Future<String> closing(int number){
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
package generator.future;
|
package generator.future;
|
||||||
|
|
||||||
public interface Waker {
|
public interface Waker {
|
||||||
|
|
||||||
|
static Waker waker() {
|
||||||
|
throw new RuntimeException("NO!");
|
||||||
|
}
|
||||||
|
|
||||||
void wake();
|
void wake();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack) {
|
||||||
return "Frame[l =" + Arrays.toString(locals) + ", s = " + Arrays.toString(stack) + "]";
|
return "Frame[l =" + Arrays.toString(locals) + ", s = " + Arrays.toString(stack) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavedStateTracker save(StateMachineBuilder smb, CodeBuilder cob, int loc_off, int stack_off) {
|
public void save_locals(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int loc_off){
|
||||||
var sst = new SavedStateTracker();
|
|
||||||
int slot = 0;
|
int slot = 0;
|
||||||
for (var entry : locals) {
|
for (var entry : locals) {
|
||||||
slot++;
|
slot++;
|
||||||
|
|
@ -21,7 +20,22 @@ public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack) {
|
||||||
|
|
||||||
sst.save_local(smb, cob, entry.toCD(), slot - smb.paramSlotOff + loc_off - 1);
|
sst.save_local(smb, cob, entry.toCD(), slot - smb.paramSlotOff + loc_off - 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public void save_stack(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int stack_off) {
|
||||||
|
for(int i = stack.length-1-stack_off; i >= 0; i --){
|
||||||
|
if(stack[i].isCategory2_2nd())continue;
|
||||||
|
sst.save_stack(smb, cob, stack[i].toCD());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavedStateTracker save(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int loc_off, int stack_off) {
|
||||||
|
save_locals(smb, cob, sst, loc_off);
|
||||||
|
save_stack(smb, cob, sst, stack_off);
|
||||||
return sst;
|
return sst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SavedStateTracker save(StateMachineBuilder smb, CodeBuilder cob, int loc_off, int stack_off) {
|
||||||
|
var sst = new SavedStateTracker();
|
||||||
|
return save(smb, cob, sst, loc_off, stack_off);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ public class SavedStateTracker {
|
||||||
smb.lstate.add(new StateMachineBuilder.LState(name, desc));
|
smb.lstate.add(new StateMachineBuilder.LState(name, desc));
|
||||||
|
|
||||||
if(TypeKind.from(desc).slotSize()==2){
|
if(TypeKind.from(desc).slotSize()==2){
|
||||||
cob.aload(0).swap().putfield(smb.CD_this, name, desc);
|
|
||||||
}else{
|
|
||||||
cob.aload(0).dup_x2().pop().putfield(smb.CD_this, name, desc);
|
cob.aload(0).dup_x2().pop().putfield(smb.CD_this, name, desc);
|
||||||
|
}else{
|
||||||
|
cob.aload(0).swap().putfield(smb.CD_this, name, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
var s = new StackState(name, desc);
|
var s = new StackState(name, desc);
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,13 @@ public class FutureSMBuilder extends StateMachineBuilder {
|
||||||
cob.ifThenElse(bcb -> {
|
cob.ifThenElse(bcb -> {
|
||||||
bcb.swap().aload(0).swap().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
bcb.swap().aload(0).swap().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
||||||
|
|
||||||
var saved = frame.save(smb, cob, 2, 0);
|
var sst = new SavedStateTracker();
|
||||||
|
frame.save_locals(smb, cob, sst,2);
|
||||||
|
bcb.storeLocal(TypeKind.REFERENCE, 2);
|
||||||
|
frame.save_stack(smb, cob, sst,1);
|
||||||
|
bcb.loadLocal(TypeKind.REFERENCE, 2);
|
||||||
bcb.areturn().labelBinding(restore_label);
|
bcb.areturn().labelBinding(restore_label);
|
||||||
saved.restore_all(smb, cob);
|
sst.restore_all(smb, cob);
|
||||||
|
|
||||||
bcb.aload(0).getfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
bcb.aload(0).getfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
||||||
bcb.aload(0).aconst_null().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
bcb.aload(0).aconst_null().putfield(smb.CD_this, AWAITING_FIELD_NAME, CD_Future);
|
||||||
|
|
@ -75,11 +79,28 @@ public class FutureSMBuilder extends StateMachineBuilder {
|
||||||
var saved = frame.save(smb, cob, 2, 0);
|
var saved = frame.save(smb, cob, 2, 0);
|
||||||
cob.aload(0).loadConstant(resume_state).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound())
|
cob.aload(0).loadConstant(resume_state).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound())
|
||||||
.getstatic(CD_Pending, "INSTANCE", CD_Pending)
|
.getstatic(CD_Pending, "INSTANCE", CD_Pending)
|
||||||
.areturn();
|
.areturn().labelBinding(resume_label);
|
||||||
saved.restore_all(smb, cob);
|
saved.restore_all(smb, cob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class WakerHandler extends SpecialMethodHandler{
|
||||||
|
|
||||||
|
protected WakerHandler(StateMachineBuilder smb, CodeBuilder cob) {
|
||||||
|
super(smb, cob);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildHandler(StateMachineBuilder smb, CodeBuilder cob, Frame frame) {
|
||||||
|
cob.aload(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReplacementKind replacementKind() {
|
||||||
|
return ReplacementKind.Immediate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class RetHandler extends SpecialMethodHandler{
|
static class RetHandler extends SpecialMethodHandler{
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,5 +143,6 @@ public class FutureSMBuilder extends StateMachineBuilder {
|
||||||
smmap.put(new SpecialMethod(CD_Future, "await", MTD_Obj), AwaitHandler::new);
|
smmap.put(new SpecialMethod(CD_Future, "await", MTD_Obj), AwaitHandler::new);
|
||||||
smmap.put(new SpecialMethod(CD_Future, "ret", MTD_Future_Obj), RetHandler::new);
|
smmap.put(new SpecialMethod(CD_Future, "ret", MTD_Future_Obj), RetHandler::new);
|
||||||
smmap.put(new SpecialMethod(CD_Future, "yield", ConstantDescs.MTD_void), YieldHandler::new);
|
smmap.put(new SpecialMethod(CD_Future, "yield", ConstantDescs.MTD_void), YieldHandler::new);
|
||||||
|
smmap.put(new SpecialMethod(CD_Waker, "waker", MethodTypeDesc.of(CD_Waker)), WakerHandler::new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue