mirror of
https://github.com/ParkerTenBroeck/coroutines.git
synced 2026-06-06 21:00:35 -04:00
added synchronized method support
This commit is contained in:
parent
2cca81977b
commit
6d05ccc690
7 changed files with 64 additions and 16 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()){
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue