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);
|
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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()){
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue