From 6d05ccc690e796775db775bdff36f0ff8775e267 Mon Sep 17 00:00:00 2001 From: Parker TenBroeck <51721964+ParkerTenBroeck@users.noreply.github.com> Date: Sat, 3 May 2025 00:10:02 -0400 Subject: [PATCH] added synchronized method support --- src/AsyncExamples.java | 10 +++++ src/Main.java | 2 + src/future/Future.java | 2 +- .../loadtime/GeneratorClassLoader.java | 2 +- .../loadtime/StateMachineBuilder.java | 41 +++++++++++++++++-- .../loadtime/future/FutureSMBuilder.java | 16 +++++--- src/generators/loadtime/gen/GenSMBuilder.java | 7 ++-- 7 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/AsyncExamples.java b/src/AsyncExamples.java index 16725cf..c605037 100644 --- a/src/AsyncExamples.java +++ b/src/AsyncExamples.java @@ -58,6 +58,16 @@ public class AsyncExamples { return Future.ret(null); } + public static synchronized Future meow(){ + Delay.delay(1000).await(); + return Future.ret(); + } + + public synchronized Future meow2(){ + Delay.delay(1000).await(); + return Future.ret(); + } + public static Future echo(Socket socket){ try(socket){ var buffer = ByteBuffer.allocate(4096*16*3); diff --git a/src/Main.java b/src/Main.java index 7b80755..61ee5ab 100644 --- a/src/Main.java +++ b/src/Main.java @@ -14,6 +14,8 @@ public class Main implements Runnable { @Override public void run() { + new Jokio().blocking(AsyncExamples.meow()); + new Jokio().blocking(new AsyncExamples().meow2()); // async_lambda(() -> { // System.out.println("START"); // Delay.delay(100).await(); diff --git a/src/future/Future.java b/src/future/Future.java index e400683..c7a1abb 100644 --- a/src/future/Future.java +++ b/src/future/Future.java @@ -18,7 +18,7 @@ public interface Future { throw new RuntimeException("NO!"); } - static Future ret(){ + static Future ret(){ throw new RuntimeException(); } diff --git a/src/generators/loadtime/GeneratorClassLoader.java b/src/generators/loadtime/GeneratorClassLoader.java index da99b89..29d2e71 100644 --- a/src/generators/loadtime/GeneratorClassLoader.java +++ b/src/generators/loadtime/GeneratorClassLoader.java @@ -74,7 +74,7 @@ public class GeneratorClassLoader extends ClassLoader { } if(builder!=null&&builder.hasAnyHandlers()){ add(builder.CD_this.displayName(), builder.buildStateMachine()); - cb.withMethod(mem.methodName(), mem.methodType(), mem.flags().flagsMask(), mb -> { + cb.withMethod(mem.methodName(), mem.methodType(), mem.flags().flagsMask()&~ClassFile.ACC_SYNCHRONIZED, mb -> { mb.withCode(builder::buildSourceMethodShim); }); if(builder.shouldBeInnerClass()){ diff --git a/src/generators/loadtime/StateMachineBuilder.java b/src/generators/loadtime/StateMachineBuilder.java index 717e159..d07bc7e 100644 --- a/src/generators/loadtime/StateMachineBuilder.java +++ b/src/generators/loadtime/StateMachineBuilder.java @@ -33,6 +33,8 @@ public abstract class StateMachineBuilder { protected final HashMap smmap = new HashMap<>(); + + record LState(String name, ClassDesc cd) { } @@ -162,24 +164,55 @@ public abstract class StateMachineBuilder { return false; } + public void nonresumable_return(CodeBuilder cob, TypeKind kind){ + this.synchronized_exit(cob); + cob.return_(kind); + } + + public void resumable_return(CodeBuilder cob, StateBuilder.State resume, TypeKind kind) { + this.synchronized_exit(cob); + cob.return_(kind); + resume.bind(cob); + } + + protected void synchronized_start(CodeBuilder cob){ + if(src_mem.flags().has(AccessFlag.SYNCHRONIZED)){ + if(src_mem.flags().has(AccessFlag.STATIC)) cob.loadConstant(src_clm.thisClass().asSymbol()); + else cob.aload(0).getfield(CD_this, PARAM_PREFIX+0, src_clm.thisClass().asSymbol()); + cob.monitorenter(); + } + } + + public void synchronized_exit(CodeBuilder cob){ + if(src_mem.flags().has(AccessFlag.SYNCHRONIZED)){ + if(src_mem.flags().has(AccessFlag.STATIC)) cob.loadConstant(src_clm.thisClass().asSymbol()); + else cob.aload(0).getfield(CD_this, PARAM_PREFIX+0, src_clm.thisClass().asSymbol()); + cob.monitorexit(); + } + } + protected abstract void buildStateMachineMethod(ClassBuilder clb); public void buildStateMachineMethodCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off){ + this.synchronized_start(cob); cob.trying( tcob -> buildStateMachineCode(clb, tcob, loc_param_off), // catch anything set our state to -1 and throw the exception ctb -> ctb.catchingAll( - blc -> - blc.aload(0).loadConstant(-1).putfield(CD_this, STATE_NAME, ConstantDescs.CD_int) - .athrow() + blc -> { + blc.aload(0).loadConstant(-1).putfield(CD_this, STATE_NAME, ConstantDescs.CD_int); + this.synchronized_exit(blc); + cob.athrow(); + } ) - ).aconst_null().areturn(); + ); } public void buildStateMachineCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off) { var stateBuilder = new StateBuilder(); var handlers = new ArrayList(); + boolean ignore_next_pop = false; var invalid_state = cob.newLabel(); diff --git a/src/generators/loadtime/future/FutureSMBuilder.java b/src/generators/loadtime/future/FutureSMBuilder.java index a6fcf24..ab11003 100644 --- a/src/generators/loadtime/future/FutureSMBuilder.java +++ b/src/generators/loadtime/future/FutureSMBuilder.java @@ -44,8 +44,9 @@ public class FutureSMBuilder extends StateMachineBuilder { cob.storeLocal(TypeKind.REFERENCE, 2); frame.save_stack(smb, cob, sst,1); cob.loadLocal(TypeKind.REFERENCE, 2); - cob.areturn(); - awaiting.bind(cob); + + smb.resumable_return(cob, awaiting, TypeKind.REFERENCE); + sst.restore_all(smb, cob); cob.goto_(resume_inline); } @@ -92,9 +93,10 @@ public class FutureSMBuilder extends StateMachineBuilder { var saved = frame.save(smb, cob, 2, 0); resume.setState(smb, cob); - cob.getstatic(CD_Pending, "INSTANCE", CD_Pending).areturn(); + cob.getstatic(CD_Pending, "INSTANCE", CD_Pending); + + smb.resumable_return(cob, resume, TypeKind.REFERENCE); - resume.bind(cob); saved.restore_all(smb, cob); cob.goto_(end); } @@ -134,7 +136,8 @@ public class FutureSMBuilder extends StateMachineBuilder { @Override public void build_inline(StateMachineBuilder smb, CodeBuilder cob, Frame frame) { - cob.aload(0).loadConstant(-1).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()).areturn(); + cob.aload(0).loadConstant(-1).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()); + smb.nonresumable_return(cob, TypeKind.REFERENCE); } } @@ -149,7 +152,8 @@ public class FutureSMBuilder extends StateMachineBuilder { @Override public void build_inline(StateMachineBuilder smb, CodeBuilder cob, Frame frame) { - cob.aload(0).loadConstant(-1).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()).aconst_null().areturn(); + cob.aload(0).loadConstant(-1).putfield(smb.CD_this, STATE_NAME, TypeKind.INT.upperBound()).aconst_null(); + smb.nonresumable_return(cob, TypeKind.REFERENCE); } } diff --git a/src/generators/loadtime/gen/GenSMBuilder.java b/src/generators/loadtime/gen/GenSMBuilder.java index e683e04..dd600f5 100644 --- a/src/generators/loadtime/gen/GenSMBuilder.java +++ b/src/generators/loadtime/gen/GenSMBuilder.java @@ -46,9 +46,8 @@ public class GenSMBuilder extends StateMachineBuilder { frame.save_stack(smb, cob, sst,1); cob.loadLocal(TypeKind.REFERENCE, 1); - cob.areturn(); + smb.resumable_return(cob, yielded, TypeKind.REFERENCE); - yielded.bind(cob); sst.restore_all(smb, cob); cob.goto_(resume); } @@ -89,8 +88,8 @@ public class GenSMBuilder extends StateMachineBuilder { .new_(CD_Ret) .dup_x1() .swap() - .invokespecial(CD_Ret, ConstantDescs.INIT_NAME, MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Object)) - .areturn(); + .invokespecial(CD_Ret, ConstantDescs.INIT_NAME, MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Object)); + smb.nonresumable_return(cob, TypeKind.REFERENCE); } }