From 90bfb8a631ec76496ae8453e2efb248d8d6cfc04 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Tue, 29 Apr 2025 13:29:12 -0400 Subject: [PATCH] fixed bug with saving stack --- src/Examples.java | 17 +++++++---- src/generator/future/Waker.java | 5 ++++ src/generator/runtime/Frame.java | 18 ++++++++++-- src/generator/runtime/SavedStateTracker.java | 4 +-- .../runtime/future/FutureSMBuilder.java | 28 +++++++++++++++++-- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/Examples.java b/src/Examples.java index 3a79f63..4aabe1d 100644 --- a/src/Examples.java +++ b/src/Examples.java @@ -2,6 +2,7 @@ import async_example.Delay; import async_example.Jokio; import async_example.Socket; import generator.future.Future; +import generator.future.Waker; import java.net.InetSocketAddress; @@ -75,13 +76,17 @@ public class Examples { return Future.ret(number+"ms"); } - public Future awaitTest(int number){ - var result = awaitTest2(number).await(); - var rt = Jokio.runtime().await(); - rt.spawn(awaitTest2(5000)); - closing(5000).await(); - return Future.ret("Result: " + result); + public Future number(int value){ + Waker.waker().wake(); + Future.yield(); + return Future.ret(value); + } + + public Future awaitTest(int number){ + var result = number(10).await()+number(20).await(); + Jokio.runtime().await().spawn(awaitTest2(5000)); + return Future.ret(""+result); } public Future closing(int number){ diff --git a/src/generator/future/Waker.java b/src/generator/future/Waker.java index f525dcd..2541766 100644 --- a/src/generator/future/Waker.java +++ b/src/generator/future/Waker.java @@ -1,5 +1,10 @@ package generator.future; public interface Waker { + + static Waker waker() { + throw new RuntimeException("NO!"); + } + void wake(); } diff --git a/src/generator/runtime/Frame.java b/src/generator/runtime/Frame.java index d1a50a4..fd10614 100644 --- a/src/generator/runtime/Frame.java +++ b/src/generator/runtime/Frame.java @@ -11,8 +11,7 @@ public record Frame(FrameTracker.Type[] locals, FrameTracker.Type[] stack) { return "Frame[l =" + Arrays.toString(locals) + ", s = " + Arrays.toString(stack) + "]"; } - public SavedStateTracker save(StateMachineBuilder smb, CodeBuilder cob, int loc_off, int stack_off) { - var sst = new SavedStateTracker(); + public void save_locals(StateMachineBuilder smb, CodeBuilder cob, SavedStateTracker sst, int loc_off){ int slot = 0; for (var entry : locals) { 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); } + } + 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; } + + 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); + } } diff --git a/src/generator/runtime/SavedStateTracker.java b/src/generator/runtime/SavedStateTracker.java index 0114e66..fd01ed9 100644 --- a/src/generator/runtime/SavedStateTracker.java +++ b/src/generator/runtime/SavedStateTracker.java @@ -19,9 +19,9 @@ public class SavedStateTracker { smb.lstate.add(new StateMachineBuilder.LState(name, desc)); 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); + }else{ + cob.aload(0).swap().putfield(smb.CD_this, name, desc); } var s = new StackState(name, desc); diff --git a/src/generator/runtime/future/FutureSMBuilder.java b/src/generator/runtime/future/FutureSMBuilder.java index 24d4a49..9c2b230 100644 --- a/src/generator/runtime/future/FutureSMBuilder.java +++ b/src/generator/runtime/future/FutureSMBuilder.java @@ -45,9 +45,13 @@ public class FutureSMBuilder extends StateMachineBuilder { cob.ifThenElse(bcb -> { 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); - 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).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); cob.aload(0).loadConstant(resume_state).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()) .getstatic(CD_Pending, "INSTANCE", CD_Pending) - .areturn(); + .areturn().labelBinding(resume_label); 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{ @@ -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, "ret", MTD_Future_Obj), RetHandler::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); } }