added synchronized method support

This commit is contained in:
Parker TenBroeck 2025-05-03 00:10:02 -04:00
parent 2cca81977b
commit 6d05ccc690
7 changed files with 64 additions and 16 deletions

View file

@ -58,6 +58,16 @@ public class AsyncExamples {
return Future.ret(null); return Future.ret(null);
} }
public static synchronized Future<Void, RuntimeException> meow(){
Delay.delay(1000).await();
return Future.ret();
}
public synchronized Future<Void, RuntimeException> meow2(){
Delay.delay(1000).await();
return Future.ret();
}
public static Future<Void, IOException> echo(Socket socket){ public static Future<Void, IOException> echo(Socket socket){
try(socket){ try(socket){
var buffer = ByteBuffer.allocate(4096*16*3); var buffer = ByteBuffer.allocate(4096*16*3);

View file

@ -14,6 +14,8 @@ public class Main implements Runnable {
@Override @Override
public void run() { public void run() {
new Jokio().blocking(AsyncExamples.meow());
new Jokio().blocking(new AsyncExamples().meow2());
// async_lambda(() -> { // async_lambda(() -> {
// System.out.println("START"); // System.out.println("START");
// Delay.delay(100).await(); // Delay.delay(100).await();

View file

@ -18,7 +18,7 @@ public interface Future<R, E extends Throwable> {
throw new RuntimeException("NO!"); throw new RuntimeException("NO!");
} }
static Future<Void, ? extends Throwable> ret(){ static <E extends Throwable> Future<Void, E> ret(){
throw new RuntimeException(); throw new RuntimeException();
} }

View file

@ -74,7 +74,7 @@ public class GeneratorClassLoader extends ClassLoader {
} }
if(builder!=null&&builder.hasAnyHandlers()){ if(builder!=null&&builder.hasAnyHandlers()){
add(builder.CD_this.displayName(), builder.buildStateMachine()); 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); mb.withCode(builder::buildSourceMethodShim);
}); });
if(builder.shouldBeInnerClass()){ if(builder.shouldBeInnerClass()){

View file

@ -33,6 +33,8 @@ public abstract class StateMachineBuilder {
protected final HashMap<SpecialMethod, SpecialMethodBuilder> smmap = new HashMap<>(); protected final HashMap<SpecialMethod, SpecialMethodBuilder> smmap = new HashMap<>();
record LState(String name, ClassDesc cd) { record LState(String name, ClassDesc cd) {
} }
@ -162,24 +164,55 @@ public abstract class StateMachineBuilder {
return false; 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); protected abstract void buildStateMachineMethod(ClassBuilder clb);
public void buildStateMachineMethodCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off){ public void buildStateMachineMethodCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off){
this.synchronized_start(cob);
cob.trying( cob.trying(
tcob -> buildStateMachineCode(clb, tcob, loc_param_off), tcob -> buildStateMachineCode(clb, tcob, loc_param_off),
// catch anything set our state to -1 and throw the exception // catch anything set our state to -1 and throw the exception
ctb -> ctb.catchingAll( ctb -> ctb.catchingAll(
blc -> blc -> {
blc.aload(0).loadConstant(-1).putfield(CD_this, STATE_NAME, ConstantDescs.CD_int) blc.aload(0).loadConstant(-1).putfield(CD_this, STATE_NAME, ConstantDescs.CD_int);
.athrow() this.synchronized_exit(blc);
cob.athrow();
}
) )
).aconst_null().areturn(); );
} }
public void buildStateMachineCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off) { public void buildStateMachineCode(ClassBuilder clb, CodeBuilder cob, int loc_param_off) {
var stateBuilder = new StateBuilder(); var stateBuilder = new StateBuilder();
var handlers = new ArrayList<SpecialMethodHandler>(); var handlers = new ArrayList<SpecialMethodHandler>();
boolean ignore_next_pop = false; boolean ignore_next_pop = false;
var invalid_state = cob.newLabel(); var invalid_state = cob.newLabel();

View file

@ -44,8 +44,9 @@ public class FutureSMBuilder extends StateMachineBuilder {
cob.storeLocal(TypeKind.REFERENCE, 2); cob.storeLocal(TypeKind.REFERENCE, 2);
frame.save_stack(smb, cob, sst,1); frame.save_stack(smb, cob, sst,1);
cob.loadLocal(TypeKind.REFERENCE, 2); cob.loadLocal(TypeKind.REFERENCE, 2);
cob.areturn();
awaiting.bind(cob); smb.resumable_return(cob, awaiting, TypeKind.REFERENCE);
sst.restore_all(smb, cob); sst.restore_all(smb, cob);
cob.goto_(resume_inline); cob.goto_(resume_inline);
} }
@ -92,9 +93,10 @@ public class FutureSMBuilder extends StateMachineBuilder {
var saved = frame.save(smb, cob, 2, 0); var saved = frame.save(smb, cob, 2, 0);
resume.setState(smb, cob); 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); saved.restore_all(smb, cob);
cob.goto_(end); cob.goto_(end);
} }
@ -134,7 +136,8 @@ public class FutureSMBuilder extends StateMachineBuilder {
@Override @Override
public void build_inline(StateMachineBuilder smb, CodeBuilder cob, Frame frame) { 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 @Override
public void build_inline(StateMachineBuilder smb, CodeBuilder cob, Frame frame) { 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);
} }
} }

View file

@ -46,9 +46,8 @@ public class GenSMBuilder extends StateMachineBuilder {
frame.save_stack(smb, cob, sst,1); frame.save_stack(smb, cob, sst,1);
cob.loadLocal(TypeKind.REFERENCE, 1); cob.loadLocal(TypeKind.REFERENCE, 1);
cob.areturn(); smb.resumable_return(cob, yielded, TypeKind.REFERENCE);
yielded.bind(cob);
sst.restore_all(smb, cob); sst.restore_all(smb, cob);
cob.goto_(resume); cob.goto_(resume);
} }
@ -89,8 +88,8 @@ public class GenSMBuilder extends StateMachineBuilder {
.new_(CD_Ret) .new_(CD_Ret)
.dup_x1() .dup_x1()
.swap() .swap()
.invokespecial(CD_Ret, ConstantDescs.INIT_NAME, MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Object)) .invokespecial(CD_Ret, ConstantDescs.INIT_NAME, MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_Object));
.areturn(); smb.nonresumable_return(cob, TypeKind.REFERENCE);
} }
} }