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);
}
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){
try(socket){
var buffer = ByteBuffer.allocate(4096*16*3);

View file

@ -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();

View file

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

View file

@ -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()){

View file

@ -33,6 +33,8 @@ public abstract class StateMachineBuilder {
protected final HashMap<SpecialMethod, SpecialMethodBuilder> 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<SpecialMethodHandler>();
boolean ignore_next_pop = false;
var invalid_state = cob.newLabel();

View file

@ -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);
}
}

View file

@ -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);
}
}